Last active
January 22, 2024 20:36
-
-
Save doeixd/bd70a6dac0b981d505e7f360532b0bdb to your computer and use it in GitHub Desktop.
framework.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createContext as unCreateContext } from 'unctx' | |
import { createFallback, isString } from './utilities.mjs' | |
// Setup | |
export function init() { | |
window.__registry = { | |
initial_component_contexts: {}, | |
component_instances: {} | |
} | |
ensureRunAfterDOM(_ => { | |
const everyElement = [...document.querySelectorAll('*')] | |
for (let element of everyElement) { | |
addFrameworkListenersToElement(element) | |
} | |
createObserver((mutations) => { | |
const addedElements = getAddedElements(mutations) | |
for (let addedElement of addedElements) { | |
addFrameworkListenersToElement(addedElement) | |
} | |
}, {childList: true, subtree: true})(document) | |
}) | |
} | |
export function getContext () { | |
return { | |
context: {}, | |
args: {} | |
} | |
} | |
export function initialComponentContexts() { | |
return window?.__registry?.context?.initial_component_contexts | |
} | |
export function getInstance(name, key) { | |
let isNameAndKey = isString(name) && isString(key) | |
if (isNameAndKey) return window?.__registry?.component_instances?.[name]?.[key] | |
if (name) return window?.__registry?.component_instances?.[name] | |
return window?.__registry?.component_instances | |
} | |
export function createInitialContextObject({name, type = 'single', data}) { | |
return { | |
...data, | |
state: {}, | |
props: {}, | |
events: {}, | |
roles: {}, | |
mount: [], | |
name, | |
parent: undefined, | |
components: [], | |
type, | |
condition: (element) => { | |
return element.tagName.toLowerCase() == name.toLowerCase() | |
}, | |
} | |
} | |
export function createComponent(name, constructor, data) { | |
const ctx = unCreateContext(name) | |
getContext = ctx.use | |
let componentContext = createInitialContextObject({name, data}) | |
function call(args = {}, fn) { | |
let context = { | |
context: componentContext, | |
args, | |
ctx, | |
call | |
} | |
// ctx.set(context, true) | |
return ctx.call(context, fn) | |
} | |
call({}, constructor) | |
getContext().__registry | |
} | |
export function component(keyNameOrFn, key) { | |
let component_context = getContext()?.context | |
let createReturnValue = (_instance = instances) => createFallback(_instance, _instance?.element || {}) | |
const isNameAndKey = isString(keyNameOrFn) && isString(key) | |
const isFn = keyNameOrFn instanceof Function | |
// const isKey = isString(keyNameOrFn) && !key | |
if (isNameAndKey) { | |
const instance = getInstance(keyNameOrFn, key) | |
return createReturnValue(instance) | |
} | |
if (isFn) { | |
let instances = Object.entries(window?.__registry?.component_instances) | |
let toReturn = [] | |
for (let instance of instances) { | |
if(keyNameOrFn?.(instance)) { | |
toReturn.push(createReturnValue(instance)) | |
} | |
} | |
} | |
let name = component_context?.name || (isString(keyNameOrFn) ? keyNameOrFn : undefined) | |
let type = component_context?.type || 'single' | |
let instances = getInstance(name) | |
let initial_component_contexts = initialComponentContexts() | |
let is_single = type.toLowerCase().includes('single') | |
if (is_single) return createReturnValue() | |
return instances.map(createReturnValue) | |
} | |
export function find() { | |
} | |
export function condition (cb) { | |
let context = getContext()?.context | |
context['condition'] = cb | |
} | |
export function key (cb) { | |
let context = getContext()?.context | |
context['key'] = cb | |
} | |
export function mount (cb) { | |
let context = getContext()?.context | |
context['mount'] ||= [] | |
context['mount'].push(cb) | |
} | |
export function prop(key, value) { | |
let context = getContext()?.context | |
context[key] = value | |
} | |
export function on (condition, cb) { | |
let context = getContext()?.context | |
context['events'] ||= [] | |
context['events'].push({condition, cb}) | |
} | |
export function attr (name, cb, initial) { | |
let context = getContext()?.context | |
context['attributes'] ||= [] | |
context['attributes'].push({name, cb, initial}) | |
} | |
export function dispatch(name, cb) { | |
let context = getContext()?.context | |
context['dispatch'] ||= [] | |
context['dispatch'].push({name, cb}) | |
} | |
export function unsubscribe(condition, cb) { | |
let context = getContext()?.context | |
context['unsubscribe'] ||= [] | |
context['unsubscribe'].push({condition, cb}) | |
} | |
export function state () { | |
let context = getContext()?.context | |
let _state = {} | |
context['state'] ||= _state | |
return _state | |
} | |
export const role_symbol = Symbol('role') | |
export const role_name_symbol = Symbol('role_name') | |
export function role(name, cb) { | |
let context = getContext()?.context | |
let full_context = getContext() | |
let isRole = Object.hasOwn(role_symbol, full_context) | |
let isCondition = name && !(cb instanceof Function) | |
if (isCondition) { | |
} | |
if (isRole) { | |
let role_context = getContext() | |
return role_context | |
} | |
if (cb instanceof Function) { | |
let _role = {} | |
context['role'] ||= _role | |
context['role'][name] = { | |
[role_symbol]: true, | |
[role_name_symbol]: name, | |
} | |
let ctx = unCreateContext() | |
let og_getContext = getContext | |
getContext = ctx.use | |
ctx.call(createFallback(context['role'][name], context), cb) | |
getContext = og_getContext | |
} | |
} | |
export function el (condition) { | |
const context = getContext() | |
let element = context?.element || context?.context?.element | |
if (!condition) { | |
return context?.element || context?.context?.element | |
} | |
if (isString(condition) && element) { | |
return element.querySelector(string) | |
} | |
if (condition instanceof Function && element) { | |
return [...element.querySelectorAll('*')].find(condition) | |
} | |
} |
Author
doeixd
commented
Jan 22, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment