sprae 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/sprae.js.map ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["node_modules/@preact/signals-core/src/index.ts", "node_modules/sube/sube.js", "node_modules/signal-struct/signal-struct.js", "src/core.js", "node_modules/element-props/element-props.js", "node_modules/swapdom/swap-inflate.js", "node_modules/primitive-pool/index.js", "src/directives.js", "src/index.js"],
4
+ "sourcesContent": ["function cycleDetected(): never {\n\tthrow new Error(\"Cycle detected\");\n}\n\n// Flags for Computed and Effect.\nconst RUNNING = 1 << 0;\nconst NOTIFIED = 1 << 1;\nconst OUTDATED = 1 << 2;\nconst DISPOSED = 1 << 3;\nconst HAS_ERROR = 1 << 4;\nconst TRACKING = 1 << 5;\n\n// A linked list node used to track dependencies (sources) and dependents (targets).\n// Also used to remember the source's last version number that the target saw.\ntype Node = {\n\t// A source whose value the target depends on.\n\t_source: Signal;\n\t_prevSource?: Node;\n\t_nextSource?: Node;\n\n\t// A target that depends on the source and should be notified when the source changes.\n\t_target: Computed | Effect;\n\t_prevTarget?: Node;\n\t_nextTarget?: Node;\n\n\t// The version number of the source that target has last seen. We use version numbers\n\t// instead of storing the source value, because source values can take arbitrary amount\n\t// of memory, and computeds could hang on to them forever because they're lazily evaluated.\n\t// Use the special value -1 to mark potentially unused but recyclable nodes.\n\t_version: number;\n\n\t// Used to remember & roll back the source's previous `._node` value when entering &\n\t// exiting a new evaluation context.\n\t_rollbackNode?: Node;\n};\n\nfunction startBatch() {\n\tbatchDepth++;\n}\n\nfunction endBatch() {\n\tif (batchDepth > 1) {\n\t\tbatchDepth--;\n\t\treturn;\n\t}\n\n\tlet error: unknown;\n\tlet hasError = false;\n\n\twhile (batchedEffect !== undefined) {\n\t\tlet effect: Effect | undefined = batchedEffect;\n\t\tbatchedEffect = undefined;\n\n\t\tbatchIteration++;\n\n\t\twhile (effect !== undefined) {\n\t\t\tconst next: Effect | undefined = effect._nextBatchedEffect;\n\t\t\teffect._nextBatchedEffect = undefined;\n\t\t\teffect._flags &= ~NOTIFIED;\n\n\t\t\tif (!(effect._flags & DISPOSED) && needsToRecompute(effect)) {\n\t\t\t\ttry {\n\t\t\t\t\teffect._callback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!hasError) {\n\t\t\t\t\t\terror = err;\n\t\t\t\t\t\thasError = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\teffect = next;\n\t\t}\n\t}\n\tbatchIteration = 0;\n\tbatchDepth--;\n\n\tif (hasError) {\n\t\tthrow error;\n\t}\n}\n\nfunction batch<T>(callback: () => T): T {\n\tif (batchDepth > 0) {\n\t\treturn callback();\n\t}\n\t/*@__INLINE__**/ startBatch();\n\ttry {\n\t\treturn callback();\n\t} finally {\n\t\tendBatch();\n\t}\n}\n\n// Currently evaluated computed or effect.\nlet evalContext: Computed | Effect | undefined = undefined;\n\n// Effects collected into a batch.\nlet batchedEffect: Effect | undefined = undefined;\nlet batchDepth = 0;\nlet batchIteration = 0;\n\n// A global version number for signals, used for fast-pathing repeated\n// computed.peek()/computed.value calls when nothing has changed globally.\nlet globalVersion = 0;\n\nfunction addDependency(signal: Signal): Node | undefined {\n\tif (evalContext === undefined) {\n\t\treturn undefined;\n\t}\n\n\tlet node = signal._node;\n\tif (node === undefined || node._target !== evalContext) {\n\t\t// `signal` is a new dependency. Create a new node dependency node, move it\n\t\t// to the front of the current context's dependency list.\n\t\tnode = {\n\t\t\t_version: 0,\n\t\t\t_source: signal,\n\t\t\t_prevSource: undefined,\n\t\t\t_nextSource: evalContext._sources,\n\t\t\t_target: evalContext,\n\t\t\t_prevTarget: undefined,\n\t\t\t_nextTarget: undefined,\n\t\t\t_rollbackNode: node,\n\t\t};\n\t\tevalContext._sources = node;\n\t\tsignal._node = node;\n\n\t\t// Subscribe to change notifications from this dependency if we're in an effect\n\t\t// OR evaluating a computed signal that in turn has subscribers.\n\t\tif (evalContext._flags & TRACKING) {\n\t\t\tsignal._subscribe(node);\n\t\t}\n\t\treturn node;\n\t} else if (node._version === -1) {\n\t\t// `signal` is an existing dependency from a previous evaluation. Reuse it.\n\t\tnode._version = 0;\n\n\t\t// If `node` is not already the current head of the dependency list (i.e.\n\t\t// there is a previous node in the list), then make `node` the new head.\n\t\tif (node._prevSource !== undefined) {\n\t\t\tnode._prevSource._nextSource = node._nextSource;\n\t\t\tif (node._nextSource !== undefined) {\n\t\t\t\tnode._nextSource._prevSource = node._prevSource;\n\t\t\t}\n\t\t\tnode._prevSource = undefined;\n\t\t\tnode._nextSource = evalContext._sources;\n\t\t\t// evalCotext._sources must be !== undefined (and !== node), because\n\t\t\t// `node` was originally pointing to some previous node.\n\t\t\tevalContext._sources!._prevSource = node;\n\t\t\tevalContext._sources = node;\n\t\t}\n\n\t\t// We can assume that the currently evaluated effect / computed signal is already\n\t\t// subscribed to change notifications from `signal` if needed.\n\t\treturn node;\n\t}\n\treturn undefined;\n}\n\ndeclare class Signal<T = any> {\n\t/** @internal */\n\t_value: unknown;\n\n\t/** @internal\n\t * Version numbers should always be >= 0, because the special value -1 is used\n\t * by Nodes to signify potentially unused but recyclable notes.\n\t */\n\t_version: number;\n\n\t/** @internal */\n\t_node?: Node;\n\n\t/** @internal */\n\t_targets?: Node;\n\n\tconstructor(value?: T);\n\n\t/** @internal */\n\t_refresh(): boolean;\n\n\t/** @internal */\n\t_subscribe(node: Node): void;\n\n\t/** @internal */\n\t_unsubscribe(node: Node): void;\n\n\tsubscribe(fn: (value: T) => void): () => void;\n\n\tvalueOf(): T;\n\n\ttoString(): string;\n\n\tpeek(): T;\n\n\tget value(): T;\n\tset value(value: T);\n}\n\n/** @internal */\nfunction Signal(this: Signal, value?: unknown) {\n\tthis._value = value;\n\tthis._version = 0;\n\tthis._node = undefined;\n\tthis._targets = undefined;\n}\n\nSignal.prototype._refresh = function () {\n\treturn true;\n};\n\nSignal.prototype._subscribe = function (node) {\n\tif (this._targets !== node && node._prevTarget === undefined) {\n\t\tnode._nextTarget = this._targets;\n\t\tif (this._targets !== undefined) {\n\t\t\tthis._targets._prevTarget = node;\n\t\t}\n\t\tthis._targets = node;\n\t}\n};\n\nSignal.prototype._unsubscribe = function (node) {\n\tconst prev = node._prevTarget;\n\tconst next = node._nextTarget;\n\tif (prev !== undefined) {\n\t\tprev._nextTarget = next;\n\t\tnode._prevTarget = undefined;\n\t}\n\tif (next !== undefined) {\n\t\tnext._prevTarget = prev;\n\t\tnode._nextTarget = undefined;\n\t}\n\tif (node === this._targets) {\n\t\tthis._targets = next;\n\t}\n};\n\nSignal.prototype.subscribe = function (fn) {\n\tconst signal = this;\n\treturn effect(function (this: Effect) {\n\t\tconst value = signal.value;\n\t\tconst flag = this._flags & TRACKING;\n\t\tthis._flags &= ~TRACKING;\n\t\ttry {\n\t\t\tfn(value);\n\t\t} finally {\n\t\t\tthis._flags |= flag;\n\t\t}\n\t});\n};\n\nSignal.prototype.valueOf = function () {\n\treturn this.value;\n};\n\nSignal.prototype.toString = function () {\n\treturn this.value + \"\";\n};\n\nSignal.prototype.peek = function () {\n\treturn this._value;\n};\n\nObject.defineProperty(Signal.prototype, \"value\", {\n\tget() {\n\t\tconst node = addDependency(this);\n\t\tif (node !== undefined) {\n\t\t\tnode._version = this._version;\n\t\t}\n\t\treturn this._value;\n\t},\n\tset(value) {\n\t\tif (value !== this._value) {\n\t\t\tif (batchIteration > 100) {\n\t\t\t\tcycleDetected();\n\t\t\t}\n\n\t\t\tthis._value = value;\n\t\t\tthis._version++;\n\t\t\tglobalVersion++;\n\n\t\t\t/**@__INLINE__*/ startBatch();\n\t\t\ttry {\n\t\t\t\tfor (\n\t\t\t\t\tlet node = this._targets;\n\t\t\t\t\tnode !== undefined;\n\t\t\t\t\tnode = node._nextTarget\n\t\t\t\t) {\n\t\t\t\t\tnode._target._notify();\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tendBatch();\n\t\t\t}\n\t\t}\n\t},\n});\n\nfunction signal<T>(value: T): Signal<T> {\n\treturn new Signal(value);\n}\n\nfunction needsToRecompute(target: Computed | Effect): boolean {\n\t// Check the dependencies for changed values. The dependency list is already\n\t// in order of use. Therefore if multiple dependencies have changed values, only\n\t// the first used dependency is re-evaluated at this point.\n\tfor (\n\t\tlet node = target._sources;\n\t\tnode !== undefined;\n\t\tnode = node._nextSource\n\t) {\n\t\t// If there's a new version of the dependency before or after refreshing,\n\t\t// or the dependency has something blocking it from refreshing at all (e.g. a\n\t\t// dependency cycle), then we need to recompute.\n\t\tif (\n\t\t\tnode._source._version !== node._version ||\n\t\t\t!node._source._refresh() ||\n\t\t\tnode._source._version !== node._version\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\t// If none of the dependencies have changed values since last recompute then the\n\t// there's no need to recompute.\n\treturn false;\n}\n\nfunction prepareSources(target: Computed | Effect) {\n\tfor (\n\t\tlet node = target._sources;\n\t\tnode !== undefined;\n\t\tnode = node._nextSource\n\t) {\n\t\tconst rollbackNode = node._source._node;\n\t\tif (rollbackNode !== undefined) {\n\t\t\tnode._rollbackNode = rollbackNode;\n\t\t}\n\t\tnode._source._node = node;\n\t\tnode._version = -1;\n\t}\n}\n\nfunction cleanupSources(target: Computed | Effect) {\n\t// At this point target._sources is a mishmash of current & former dependencies.\n\t// The current dependencies are also in a reverse order of use.\n\t// Therefore build a new, reverted list of dependencies containing only the current\n\t// dependencies in a proper order of use.\n\t// Drop former dependencies from the list and unsubscribe from their change notifications.\n\n\tlet node = target._sources;\n\tlet sources = undefined;\n\twhile (node !== undefined) {\n\t\tconst next = node._nextSource;\n\t\tif (node._version === -1) {\n\t\t\tnode._source._unsubscribe(node);\n\t\t\tnode._nextSource = undefined;\n\t\t} else {\n\t\t\tif (sources !== undefined) {\n\t\t\t\tsources._prevSource = node;\n\t\t\t}\n\t\t\tnode._prevSource = undefined;\n\t\t\tnode._nextSource = sources;\n\t\t\tsources = node;\n\t\t}\n\n\t\tnode._source._node = node._rollbackNode;\n\t\tif (node._rollbackNode !== undefined) {\n\t\t\tnode._rollbackNode = undefined;\n\t\t}\n\t\tnode = next;\n\t}\n\ttarget._sources = sources;\n}\n\ndeclare class Computed<T = any> extends Signal<T> {\n\t_compute: () => T;\n\t_sources?: Node;\n\t_globalVersion: number;\n\t_flags: number;\n\n\tconstructor(compute: () => T);\n\n\t_notify(): void;\n\tget value(): T;\n}\n\nfunction Computed(this: Computed, compute: () => unknown) {\n\tSignal.call(this, undefined);\n\n\tthis._compute = compute;\n\tthis._sources = undefined;\n\tthis._globalVersion = globalVersion - 1;\n\tthis._flags = OUTDATED;\n}\n\nComputed.prototype = new Signal() as Computed;\n\nComputed.prototype._refresh = function () {\n\tthis._flags &= ~NOTIFIED;\n\n\tif (this._flags & RUNNING) {\n\t\treturn false;\n\t}\n\n\t// If this computed signal has subscribed to updates from its dependencies\n\t// (TRACKING flag set) and none of them have notified about changes (OUTDATED\n\t// flag not set), then the computed value can't have changed.\n\tif ((this._flags & (OUTDATED | TRACKING)) === TRACKING) {\n\t\treturn true;\n\t}\n\tthis._flags &= ~OUTDATED;\n\n\tif (this._globalVersion === globalVersion) {\n\t\treturn true;\n\t}\n\tthis._globalVersion = globalVersion;\n\n\t// Mark this computed signal running before checking the dependencies for value\n\t// changes, so that the RUNNIN flag can be used to notice cyclical dependencies.\n\tthis._flags |= RUNNING;\n\tif (this._version > 0 && !needsToRecompute(this)) {\n\t\tthis._flags &= ~RUNNING;\n\t\treturn true;\n\t}\n\n\tconst prevContext = evalContext;\n\ttry {\n\t\tprepareSources(this);\n\t\tevalContext = this;\n\t\tconst value = this._compute();\n\t\tif (\n\t\t\tthis._flags & HAS_ERROR ||\n\t\t\tthis._value !== value ||\n\t\t\tthis._version === 0\n\t\t) {\n\t\t\tthis._value = value;\n\t\t\tthis._flags &= ~HAS_ERROR;\n\t\t\tthis._version++;\n\t\t}\n\t} catch (err) {\n\t\tthis._value = err;\n\t\tthis._flags |= HAS_ERROR;\n\t\tthis._version++;\n\t}\n\tevalContext = prevContext;\n\tcleanupSources(this);\n\tthis._flags &= ~RUNNING;\n\treturn true;\n};\n\nComputed.prototype._subscribe = function (node) {\n\tif (this._targets === undefined) {\n\t\tthis._flags |= OUTDATED | TRACKING;\n\n\t\t// A computed signal subscribes lazily to its dependencies when the it\n\t\t// gets its first subscriber.\n\t\tfor (\n\t\t\tlet node = this._sources;\n\t\t\tnode !== undefined;\n\t\t\tnode = node._nextSource\n\t\t) {\n\t\t\tnode._source._subscribe(node);\n\t\t}\n\t}\n\tSignal.prototype._subscribe.call(this, node);\n};\n\nComputed.prototype._unsubscribe = function (node) {\n\tSignal.prototype._unsubscribe.call(this, node);\n\n\t// Computed signal unsubscribes from its dependencies from it loses its last subscriber.\n\tif (this._targets === undefined) {\n\t\tthis._flags &= ~TRACKING;\n\n\t\tfor (\n\t\t\tlet node = this._sources;\n\t\t\tnode !== undefined;\n\t\t\tnode = node._nextSource\n\t\t) {\n\t\t\tnode._source._unsubscribe(node);\n\t\t}\n\t}\n};\n\nComputed.prototype._notify = function () {\n\tif (!(this._flags & NOTIFIED)) {\n\t\tthis._flags |= OUTDATED | NOTIFIED;\n\n\t\tfor (\n\t\t\tlet node = this._targets;\n\t\t\tnode !== undefined;\n\t\t\tnode = node._nextTarget\n\t\t) {\n\t\t\tnode._target._notify();\n\t\t}\n\t}\n};\n\nComputed.prototype.peek = function () {\n\tif (!this._refresh()) {\n\t\tcycleDetected();\n\t}\n\tif (this._flags & HAS_ERROR) {\n\t\tthrow this._value;\n\t}\n\treturn this._value;\n};\n\nObject.defineProperty(Computed.prototype, \"value\", {\n\tget() {\n\t\tif (this._flags & RUNNING) {\n\t\t\tcycleDetected();\n\t\t}\n\t\tconst node = addDependency(this);\n\t\tthis._refresh();\n\t\tif (node !== undefined) {\n\t\t\tnode._version = this._version;\n\t\t}\n\t\tif (this._flags & HAS_ERROR) {\n\t\t\tthrow this._value;\n\t\t}\n\t\treturn this._value;\n\t},\n});\n\ninterface ReadonlySignal<T = any> extends Signal<T> {\n\treadonly value: T;\n}\n\nfunction computed<T>(compute: () => T): ReadonlySignal<T> {\n\treturn new Computed(compute);\n}\n\nfunction cleanupEffect(effect: Effect) {\n\tconst cleanup = effect._cleanup;\n\teffect._cleanup = undefined;\n\n\tif (typeof cleanup === \"function\") {\n\t\t/*@__INLINE__**/ startBatch();\n\n\t\t// Run cleanup functions always outside of any context.\n\t\tconst prevContext = evalContext;\n\t\tevalContext = undefined;\n\t\ttry {\n\t\t\tcleanup();\n\t\t} catch (err) {\n\t\t\teffect._flags &= ~RUNNING;\n\t\t\teffect._flags |= DISPOSED;\n\t\t\tdisposeEffect(effect);\n\t\t\tthrow err;\n\t\t} finally {\n\t\t\tevalContext = prevContext;\n\t\t\tendBatch();\n\t\t}\n\t}\n}\n\nfunction disposeEffect(effect: Effect) {\n\tfor (\n\t\tlet node = effect._sources;\n\t\tnode !== undefined;\n\t\tnode = node._nextSource\n\t) {\n\t\tnode._source._unsubscribe(node);\n\t}\n\teffect._compute = undefined;\n\teffect._sources = undefined;\n\n\tcleanupEffect(effect);\n}\n\nfunction endEffect(this: Effect, prevContext?: Computed | Effect) {\n\tif (evalContext !== this) {\n\t\tthrow new Error(\"Out-of-order effect\");\n\t}\n\tcleanupSources(this);\n\tevalContext = prevContext;\n\n\tthis._flags &= ~RUNNING;\n\tif (this._flags & DISPOSED) {\n\t\tdisposeEffect(this);\n\t}\n\tendBatch();\n}\n\ndeclare class Effect {\n\t_compute?: () => unknown;\n\t_cleanup?: unknown;\n\t_sources?: Node;\n\t_nextBatchedEffect?: Effect;\n\t_flags: number;\n\n\tconstructor(compute: () => void);\n\n\t_callback(): void;\n\t_start(): () => void;\n\t_notify(): void;\n\t_dispose(): void;\n}\n\nfunction Effect(this: Effect, compute: () => void) {\n\tthis._compute = compute;\n\tthis._cleanup = undefined;\n\tthis._sources = undefined;\n\tthis._nextBatchedEffect = undefined;\n\tthis._flags = TRACKING;\n}\n\nEffect.prototype._callback = function () {\n\tconst finish = this._start();\n\ttry {\n\t\tif (!(this._flags & DISPOSED) && this._compute !== undefined) {\n\t\t\tthis._cleanup = this._compute();\n\t\t}\n\t} finally {\n\t\tfinish();\n\t}\n};\n\nEffect.prototype._start = function () {\n\tif (this._flags & RUNNING) {\n\t\tcycleDetected();\n\t}\n\tthis._flags |= RUNNING;\n\tthis._flags &= ~DISPOSED;\n\tcleanupEffect(this);\n\tprepareSources(this);\n\n\t/*@__INLINE__**/ startBatch();\n\tconst prevContext = evalContext;\n\tevalContext = this;\n\treturn endEffect.bind(this, prevContext);\n};\n\nEffect.prototype._notify = function () {\n\tif (!(this._flags & NOTIFIED)) {\n\t\tthis._flags |= NOTIFIED;\n\t\tthis._nextBatchedEffect = batchedEffect;\n\t\tbatchedEffect = this;\n\t}\n};\n\nEffect.prototype._dispose = function () {\n\tthis._flags |= DISPOSED;\n\n\tif (!(this._flags & RUNNING)) {\n\t\tdisposeEffect(this);\n\t}\n};\n\nfunction effect(compute: () => unknown): () => void {\n\tconst effect = new Effect(compute);\n\teffect._callback();\n\t// Return a bound function instead of a wrapper like `() => effect._dispose()`,\n\t// because bound functions seem to be just as fast and take up a lot less memory.\n\treturn effect._dispose.bind(effect);\n}\n\nexport { signal, computed, effect, batch, Signal, ReadonlySignal };\n", "// lil subscriby (v-less)\r\nSymbol.observable||=Symbol('observable')\r\n\r\n// is target observable\r\nexport const observable = arg => arg && !!(\r\n arg[Symbol.observable] || arg[Symbol.asyncIterator] ||\r\n arg.call && arg.set ||\r\n arg.subscribe || arg.then\r\n // || arg.mutation && arg._state != null\r\n)\r\n\r\n// cleanup subscriptions\r\n// ref: https://v8.dev/features/weak-references\r\n// FIXME: maybe there's smarter way to unsubscribe in weakref, like, wrapping target in weakref?\r\nconst registry = new FinalizationRegistry(unsub => unsub.call?.()),\r\n\r\n// this thingy must lose target out of context to let gc hit\r\nunsubr = sub => sub && (() => sub.unsubscribe?.())\r\n\r\nexport default (target, next, error, complete, stop, unsub) => target && (\r\n unsub = unsubr((target[Symbol.observable]?.() || target).subscribe?.( next, error, complete )) ||\r\n target.set && target.call?.(stop, next) || // observ\r\n (\r\n target.then?.(v => (!stop && next(v), complete?.()), error) ||\r\n (async v => {\r\n try {\r\n // FIXME: possible drawback: it will catch error happened in next, not only in iterator\r\n for await (v of target) { if (stop) return; next(v) }\r\n complete?.()\r\n } catch (err) { error?.(err) }\r\n })()\r\n ) && (_ => stop=1),\r\n\r\n // register autocleanup\r\n registry.register(target, unsub),\r\n unsub\r\n)\r\n", "import { signal, computed } from '@preact/signals-core'\nimport sube, { observable } from 'sube'\n\nconst isSignal = v => v && v.peek\nconst isStruct = (v) => v[_struct]\nconst _struct = Symbol('signal-struct')\n\nexport default function SignalStruct (values) {\n if (isStruct(values)) return values;\n\n // define signal accessors\n // FIXME: alternately can be done as Proxy for extended support\n let state, signals\n if (isObject(values)) {\n state = {}, signals = {}\n for (let key in values) signals[key] = defineSignal(state, key, values[key])\n }\n else throw Error('Only array or object states are supported')\n\n Object.defineProperty(state, _struct, {configurable:false,enumerable:false,value:true})\n\n Object.seal(state)\n\n return state\n}\n\n// defines signal accessor on an object\nexport function defineSignal (state, key, value) {\n let isObservable, s = isSignal(value) ? value :\n isObject(value) ? signal(SignalStruct(value)) :\n signal((isObservable = observable(value)) ? undefined : value)\n\n if (isObservable) sube(value, v => s.value = v)\n\n Object.defineProperty(state, key, {\n get() { return s.value },\n set:\n isSignal(value) ? v => s.value = v :\n isObject(value) ? v => (v ? Object.assign(s.value, v) : s.value = v) :\n v => s.value = v\n ,\n enumerable: true,\n configurable: false\n })\n\n return s\n}\n\nfunction isObject(v) {\n return v && v.constructor === Object\n}", "import signalStruct from 'signal-struct';\n\n// sprae element: apply directives\nconst memo = new WeakMap\nexport default function sprae(container, values) {\n if (!container.children) return\n if (memo.has(container)) return memo.get(container)\n\n values ||= {};\n\n const state = signalStruct(values);\n\n // init directives on element\n const init = (el) => {\n let dir, stop\n if (el.attributes) {\n for (let i = 0; i < el.attributes.length;) {\n let attr = el.attributes[i]\n if (attr.name[0]===':') {\n dir = directives[attr.name] || directives.default\n el.removeAttribute(attr.name)\n if (stop = (dir(el, attr.value, state, attr.name.slice(1))===false)) break\n }\n else i++\n }\n }\n if (!stop) for (let child of el.children) init(child)\n }\n init(container)\n\n memo.set(container, state);\n\n return state;\n}\n\n\n// dict of directives\nexport const directives = {}", "// auto-parse pkg in 2 lines (no object/array detection)\nexport const parse = ( v, Type ) => (\n Type = Type === Object ? JSON.parse : Type === Array ? s => JSON.parse(s[0]==='['?s:`[${s}]`) : Type,\n v === '' && Type !== String ? true : Type ? Type(v) : !v || isNaN(+v) ? v : +v\n),\n\nprop = (el, k, v) => {\n // onClick \u2192 onclick, someProp -> some-prop\n if (k.startsWith('on')) k = k.toLowerCase()\n\n if (el[k] !== v) {\n // avoid readonly props https://jsperf.com/element-own-props-set/1\n // ignoring that: it's too heavy, same time it's fine to throw error for users to avoid setting form\n // let desc; if (!(k in el.constructor.prototype) || !(desc = Object.getOwnPropertyDescriptor(el.constructor.prototype, k)) || desc.set)\n el[k] = v;\n }\n\n if (v === false || v == null) el.removeAttribute(k)\n else if (typeof v !== 'function') el.setAttribute(dashcase(k),\n v === true ? '' :\n (typeof v === 'number' || typeof v === 'string') ? v :\n (k === 'class') ? (Array.isArray(v) ? v : Object.entries(v).map(([k,v])=>v?k:'')).filter(Boolean).join(' ') :\n (k === 'style') ? Object.entries(v).map(([k,v]) => `${k}: ${v}`).join(';') :\n ''\n )\n},\n\n// create input element getter/setter\ninput = (el) => [\n (el.type === 'checkbox' ? () => el.checked : () => el.value),\n (\n el.type === 'text' || el.type === '' ? value => (el.value = value == null ? '' : value) :\n el.type === 'checkbox' ? value => (el.value = value ? 'on' : '', prop(el, 'checked', value)) :\n el.type === 'select-one' ? value => (\n [...el.options].map(el => el.removeAttribute('selected')),\n el.value = value,\n el.selectedOptions[0]?.setAttribute('selected', '')\n ) :\n value => el.value = value\n )\n]\n\nexport default (el, types, onchange) => {\n // inputs\n const isInput = (el.tagName === 'INPUT' || el.tagName === 'SELECT'),\n [iget, iset] = input(el),\n p = new Proxy(el.attributes, {\n get: (attrs, k, attr) => (\n isInput && k === 'value' ? iget() :\n // k === 'children' ? [...el.childNodes] :\n k in el ? el[k] : (attr = attrs[dashcase(k)], attr && (attr.call ? attr : parse(attr.value, types?.[k])))\n ),\n set: (attrs, k, v) => (\n isInput && k === 'value' ? iset(v) : prop(el, k, parse(v, types?.[k])),\n onchange?.(k, v, attrs), 1\n ),\n\n deleteProperty: (_,k,u) => (el.removeAttribute(k), el[k]=u, delete el[k]), // events cannot be deleted, but have to be nullified\n\n // spread https://github.com/tc39/proposal-object-rest-spread/issues/69#issuecomment-633232470\n getOwnPropertyDescriptor: a => ({ enumerable: true, configurable: true }),\n ownKeys: attrs => Array.from(\n // joined props from element keys and real attributes\n new Set([...Object.keys(el), ...Object.getOwnPropertyNames(attrs)].filter(k => el[k] !== p && isNaN(+k)))\n )\n });\n\n // normalize initial input.value\n if (isInput) iset(iget())\n\n return p\n}\n\nconst el = document.createElement('div')\nconst dashcase = (str) => {\n el.dataset[str] = ''\n let dashStr = el.attributes[0].name.slice(5)\n delete el.dataset[str]\n return dashStr\n}", "// inflate version of differ, ~260b\r\n// + no sets / maps used\r\n// + prepend/append/remove/clear short paths\r\n// + a can be live childNodes/HTMLCollection\r\n\r\nconst swap = (parent, a, b, end = null) => {\r\n let i = 0, cur, next, bi, n = b.length, m = a.length, { remove, same, insert, replace } = swap\r\n\r\n // skip head/tail\r\n while (i < n && i < m && same(a[i], b[i])) i++\r\n while (i < n && i < m && same(b[n-1], a[m-1])) end = b[--m, --n]\r\n\r\n // append/prepend/trim shortcuts\r\n if (i == m) while (i < n) insert(end, b[i++], parent)\r\n // FIXME: can't use shortcut for childNodes as input\r\n // if (i == n) while (i < m) parent.removeChild(a[i++])\r\n\r\n else {\r\n cur = a[i]\r\n\r\n while (i < n) {\r\n bi = b[i++], next = cur ? cur.nextSibling : end\r\n\r\n // skip\r\n if (same(cur, bi)) cur = next\r\n\r\n // swap / replace\r\n else if (i < n && same(b[i], next)) (replace(cur, bi, parent), cur = next)\r\n\r\n // insert\r\n else insert(cur, bi, parent)\r\n }\r\n\r\n // remove tail\r\n while (!same(cur, end)) (next = cur.nextSibling, remove(cur, parent), cur = next)\r\n }\r\n\r\n return b\r\n}\r\n\r\nswap.same = (a,b) => a == b\r\nswap.replace = (a,b, parent) => parent.replaceChild(b, a)\r\nswap.insert = (a,b, parent) => parent.insertBefore(b, a)\r\nswap.remove = (a, parent) => parent.removeChild(a)\r\n\r\n\r\nexport default swap\r\n", "var cache = {}, nullObj = {}, undefinedObj = {}\n\nexport default (key) => {\n\tif (key === null) return nullObj\n\n\tif (key === undefined) return undefinedObj\n\n\tif (typeof key === 'number' || key instanceof Number)\n\t\treturn cache[key] || (cache[key] = new Number(key))\n\n\tif (typeof key === 'string' || key instanceof String)\n\t\treturn cache[key] || (cache[key] = new String(key))\n\n\tif (typeof key === 'boolean' || key instanceof Boolean)\n\t\treturn cache[key] || (cache[key] = new Boolean(key))\n\n\t// treat any other non-primitive key directly\n\treturn key\n}\n", "// directives & parsing\nimport sprae, { directives } from './core.js'\nimport { prop, input } from 'element-props'\n// import { effect, computed, batch } from 'usignal'\nimport { effect, computed, batch } from '@preact/signals-core'\nimport swap from 'swapdom'\nimport p from 'primitive-pool'\n\ndirectives[':with'] = (el, expr, rootState) => {\n let evaluate = parseExpr(expr, 'with', rootState)\n\n // Instead of extending signals (which is a bit hard since signal-struct internals is not uniform)\n // we bind updating\n const params = computed(() => Object.assign({}, rootState, evaluate(rootState)))\n let state = sprae(el, params.value)\n effect((values=params.value) => batch(() => Object.assign(state, values)))\n return false\n}\n\ndirectives[':ref'] = (el, expr, state) => {\n // note: must come after :each\n if (el.hasAttribute(':each')) { return el.setAttribute(':ref', expr) }\n\n sprae(el, Object.assign(Object.create(state), {[expr]: el}))\n return false\n}\n\ndirectives[':if'] = (el, expr, state) => {\n let holder = document.createTextNode(''),\n clauses = [parseExpr(expr, ':if', state)],\n els = [el], cur = el\n\n while (cur = el.nextElementSibling) {\n if (cur.hasAttribute(':else')) {\n cur.removeAttribute(':else');\n if (expr = cur.getAttribute(':if')) {\n cur.removeAttribute(':if'), cur.remove();\n els.push(cur); clauses.push(parseExpr(expr, ':else :if', state));\n }\n else {\n cur.remove(); els.push(cur); clauses.push(() => 1);\n }\n }\n else break;\n }\n\n el.replaceWith(cur = holder)\n let idx = computed(() => clauses.findIndex(f => f(state)))\n // NOTE: it lazily initializes elements on insertion, it's safe to sprae multiple times\n effect((i=idx.value) => (els[i] != cur && ((cur[_eachHolder]||cur).replaceWith(cur = els[i] || holder), sprae(cur, state))))\n\n return false\n}\n\nconst _eachHolder = Symbol(':each')\ndirectives[':each'] = (tpl, expr, state) => {\n let each = parseForExpression(expr);\n if (!each) return exprError(new Error, expr);\n\n const getItems = parseExpr(each.items, ':each', state);\n\n // FIXME: make sure no memory leak here\n // we need holder to be able :if replace it instead of tpl for combined case\n const holder = tpl[_eachHolder] = document.createTextNode('')\n tpl.replaceWith(holder)\n\n const items = computed(()=>{\n let list = getItems(state)\n if (!list) return []\n if (typeof list === 'number') return Array.from({length: list}, (_, i)=>[i, i+1])\n if (list.constructor === Object) return Object.entries(list)\n if (Array.isArray(list)) return list.map((item,i) => [i+1, item])\n exprError(Error('Bad list value'), each.items, ':each', list)\n })\n\n // stores scope per data item\n const scopes = new WeakMap()\n // element per data item\n const itemEls = new WeakMap()\n let curEls = []\n effect((list=items.value) => {\n // collect elements/scopes for items\n let newEls = [], elScopes = []\n\n for (let [idx, item] of list) {\n let itemKey = p(item)\n let el = itemEls.get(itemKey)\n if (!el) {\n el = tpl.cloneNode(true)\n itemEls.set(itemKey, el)\n }\n newEls.push(el)\n\n if (!scopes.has(itemKey)) {\n let scope = Object.create(state)\n scope[each.item] = item\n if (each.index) scope[each.index] = idx;\n scopes.set(itemKey, scope)\n }\n elScopes.push(scopes.get(itemKey))\n }\n\n // swap is really fast & tiny\n swap(holder.parentNode, curEls, newEls, holder)\n curEls = newEls\n\n // init new elements\n for (let i = 0; i < newEls.length; i++) {\n sprae(newEls[i], elScopes[i])\n }\n })\n\n return false\n}\n\n// This was taken AlpineJS, former VueJS 2.* core. Thanks Alpine & Vue!\nfunction parseForExpression(expression) {\n let forIteratorRE = /,([^,\\}\\]]*)(?:,([^,\\}\\]]*))?$/\n let stripParensRE = /^\\s*\\(|\\)\\s*$/g\n let forAliasRE = /([\\s\\S]*?)\\s+(?:in|of)\\s+([\\s\\S]*)/\n let inMatch = expression.match(forAliasRE)\n\n if (!inMatch) return\n\n let res = {}\n res.items = inMatch[2].trim()\n let item = inMatch[1].replace(stripParensRE, '').trim()\n let iteratorMatch = item.match(forIteratorRE)\n\n if (iteratorMatch) {\n res.item = item.replace(forIteratorRE, '').trim()\n res.index = iteratorMatch[1].trim()\n } else {\n res.item = item\n }\n\n return res\n}\n\n\n// common-setter directives\ndirectives['default'] = (el, expr, state, name) => {\n let evaluate = parseExpr(expr, ':'+name, state)\n const update = value => prop(el, name, value)\n effect(() => update(evaluate(state)))\n}\n\ndirectives[':aria'] = (el, expr, state) => {\n let evaluate = parseExpr(expr, ':aria', state)\n const update = (value) => {\n for (let key in value) prop(el, 'aria'+key[0].toUpperCase()+key.slice(1), value[key] == null ? null : value[key] + '');\n }\n effect(() => update(evaluate(state)))\n}\n\ndirectives[':data'] = (el, expr, state) => {\n let evaluate = parseExpr(expr, ':data', state)\n const value = computed(() => evaluate(state))\n effect((v=value.value) => {\n for (let key in v) el.dataset[key] = v[key];\n })\n}\n\ndirectives[':on'] = (el, expr, state) => {\n let evaluate = parseExpr(expr, ':on', state)\n let listeners = computed(() => evaluate(state))\n let prevListeners\n effect((values=listeners.value) => {\n for (let evt in prevListeners) el.removeEventListener(evt, prevListeners[evt]);\n prevListeners = values;\n for (let evt in prevListeners) el.addEventListener(evt, prevListeners[evt]);\n })\n}\n\ndirectives[':'] = (el, expr, state) => {\n let evaluate = parseExpr(expr, ':', state)\n const update = (value) => {\n if (!value) return\n for (let key in value) prop(el, key, value[key]);\n }\n effect(()=>update(evaluate(state)))\n}\n\ndirectives[':text'] = (el, expr, state) => {\n let evaluate = parseExpr(expr, ':text', state)\n\n const update = (value) => {\n el.textContent = value == null ? '' : value;\n }\n\n effect(()=>update(evaluate(state)))\n}\n\n// connect expr to element value\ndirectives[':value'] = (el, expr, state) => {\n let evaluate = parseExpr(expr, ':in', state)\n\n let [get, set] = input(el);\n\n const update = (value) => {\n prop(el, 'value', value)\n set(value);\n }\n effect(()=>update(evaluate(state)))\n}\n\nlet evaluatorMemo = {}\n\n// borrowed from alpine: https://github.com/alpinejs/alpine/blob/main/packages/alpinejs/src/evaluator.js#L61\n// it seems to be more robust than subscript\nfunction parseExpr(expression, dir, scope) {\n if (evaluatorMemo[expression]) return evaluatorMemo[expression]\n\n // Some expressions that are useful in Alpine are not valid as the right side of an expression.\n // Here we'll detect if the expression isn't valid for an assignement and wrap it in a self-\n // calling function so that we don't throw an error AND a \"return\" statement can b e used.\n let rightSideSafeExpression = 0\n // Support expressions starting with \"if\" statements like: \"if (...) doSomething()\"\n || /^[\\n\\s]*if.*\\(.*\\)/.test(expression)\n // Support expressions starting with \"let/const\" like: \"let foo = 'bar'\"\n || /^(let|const)\\s/.test(expression)\n ? `(() => { ${expression} })()`\n : expression;\n\n // guard static-time eval errors\n let evaluate\n try {\n evaluate = new Function(['scope'], `let result; with (scope) { result = (${rightSideSafeExpression}) }; return result;`)\n } catch ( e ) {\n return exprError(e, expression, dir, scope)\n }\n\n // guard runtime eval errors\n return evaluatorMemo[expression] = (state) => {\n let result\n try { result = evaluate(state) }\n catch (e) { return exprError(e, expression, dir, scope) }\n return result\n }\n}\n\nexport function exprError(error, expression, dir, scope) {\n Object.assign( error, { expression } )\n console.warn(`\u2234sprae: ${error.message}\\n\\n${dir}=${ expression ? `\"${expression}\"\\n\\n` : '' }`, scope)\n setTimeout(() => { throw error }, 0)\n}\n", "import sprae from './core.js';\nimport './directives.js';\n\nexport default sprae;\nexport { signal, computed, batch, effect } from '@preact/signals-core';\n\n// autoinit\n// NOTE: abandoning for now, since requires a separate non-module JS entry, until use-case appears\n// const s = document.currentScript\n// if (s && s.hasAttribute('init')) {\n// sprae(document.documentElement)\n// }\n"],
5
+ "mappings": "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",
6
+ "names": ["cycleDetected", "Error", "endBatch", "batchDepth", "error", "hasError", "batchedEffect", "effect", "batchIteration", "next", "_nextBatchedEffect", "_flags", "needsToRecompute", "_callback", "err", "batch", "callback", "evalContext", "globalVersion", "addDependency", "signal", "node", "_node", "_target", "_sources", "_version", "_source", "_prevSource", "_nextSource", "_prevTarget", "_nextTarget", "_rollbackNode", "_subscribe", "Signal", "value", "this", "_value", "_targets", "prototype", "_refresh", "_unsubscribe", "prev", "subscribe", "fn", "flag", "valueOf", "toString", "peek", "Object", "defineProperty", "get", "set", "_notify", "target", "prepareSources", "rollbackNode", "cleanupSources", "sources", "Computed", "compute", "call", "undefined", "_compute", "_globalVersion", "prevContext", "OUTDATED", "computed", "cleanupEffect", "cleanup", "_cleanup", "disposeEffect", "endEffect", "Effect", "finish", "_start", "bind", "_dispose", "v", "_", "v", "s", "el", "i", "el", "v", "k", "a", "b", "i", "n", "el", "f", "i", "_", "v", "e"]
7
+ }
package/sprae.min.js CHANGED
@@ -1 +1 @@
1
- function t(){throw new Error("Cycle detected")}function e(){if(o>1)o--;else{for(var t,e=!1;void 0!==n;){var i=n;for(n=void 0,s++;void 0!==i;){var r=i.o;if(i.o=void 0,i.f&=-3,!(8&i.f)&&h(i))try{i.c()}catch(i){e||(t=i,e=!0)}i=r}}if(s=0,o--,e)throw t}}var r=void 0,n=void 0,o=0,s=0,f=0;function a(t){if(void 0!==r){var e=t.n;if(void 0===e||e.t!==r)return r.s=e={i:0,S:t,p:void 0,n:r.s,t:r,e:void 0,x:void 0,r:e},t.n=e,32&r.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.p&&(e.p.n=e.n,void 0!==e.n&&(e.n.p=e.p),e.p=void 0,e.n=r.s,r.s.p=e,r.s=e),e}}function u(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function l(t){return new u(t)}function h(t){for(var e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return!0;return!1}function v(t){for(var e=t.s;void 0!==e;e=e.n){var i=e.S.n;void 0!==i&&(e.r=i),e.S.n=e,e.i=-1}}function c(t){for(var e=t.s,i=void 0;void 0!==e;){var r=e.n;-1===e.i?(e.S.U(e),e.n=void 0):(void 0!==i&&(i.p=e),e.p=void 0,e.n=i,i=e),e.S.n=e.r,void 0!==e.r&&(e.r=void 0),e=r}t.s=i}function d(t){u.call(this,void 0),this.x=t,this.s=void 0,this.g=f-1,this.f=4}function p(t){return new d(t)}function y(t){var i=t.u;if(t.u=void 0,"function"==typeof i){o++;var n=r;r=void 0;try{i()}catch(e){throw t.f&=-2,t.f|=8,b(t),e}finally{r=n,e()}}}function b(t){for(var e=t.s;void 0!==e;e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,y(t)}function m(t){if(r!==this)throw new Error("Out-of-order effect");c(this),r=t,this.f&=-2,8&this.f&&b(this),e()}function g(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function S(t){var e=new g(t);return e.c(),e.d.bind(e)}u.prototype.h=function(){return!0},u.prototype.S=function(t){this.t!==t&&void 0===t.e&&(t.x=this.t,void 0!==this.t&&(this.t.e=t),this.t=t)},u.prototype.U=function(t){var e=t.e,i=t.x;void 0!==e&&(e.x=i,t.e=void 0),void 0!==i&&(i.e=e,t.x=void 0),t===this.t&&(this.t=i)},u.prototype.subscribe=function(t){var e=this;return S((function(){var i=e.value,r=32&this.f;this.f&=-33;try{t(i)}finally{this.f|=r}}))},u.prototype.valueOf=function(){return this.value},u.prototype.toString=function(){return this.value+""},u.prototype.peek=function(){return this.v},Object.defineProperty(u.prototype,"value",{get:function(){var t=a(this);return void 0!==t&&(t.i=this.i),this.v},set:function(i){if(i!==this.v){s>100&&t(),this.v=i,this.i++,f++,o++;try{for(var r=this.t;void 0!==r;r=r.x)r.t.N()}finally{e()}}}}),(d.prototype=new u).h=function(){if(this.f&=-3,1&this.f)return!1;if(32==(36&this.f))return!0;if(this.f&=-5,this.g===f)return!0;if(this.g=f,this.f|=1,this.i>0&&!h(this))return this.f&=-2,!0;var t=r;try{v(this),r=this;var e=this.x();(16&this.f||this.v!==e||0===this.i)&&(this.v=e,this.f&=-17,this.i++)}catch(t){this.v=t,this.f|=16,this.i++}return r=t,c(this),this.f&=-2,!0},d.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(var e=this.s;void 0!==e;e=e.n)e.S.S(e)}u.prototype.S.call(this,t)},d.prototype.U=function(t){if(u.prototype.U.call(this,t),void 0===this.t){this.f&=-33;for(var e=this.s;void 0!==e;e=e.n)e.S.U(e)}},d.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var t=this.t;void 0!==t;t=t.x)t.t.N()}},d.prototype.peek=function(){if(this.h()||t(),16&this.f)throw this.v;return this.v},Object.defineProperty(d.prototype,"value",{get:function(){1&this.f&&t();var e=a(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),g.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},g.prototype.S=function(){1&this.f&&t(),this.f|=1,this.f&=-9,y(this),v(this),o++;var e=r;return r=this,m.bind(this,e)},g.prototype.N=function(){2&this.f||(this.f|=2,this.o=n,n=this)},g.prototype.d=function(){this.f|=8,1&this.f||b(this)},Symbol.observable||=Symbol("observable");var x=new FinalizationRegistry((t=>t.call?.())),w=t=>t&&t.peek,O=Symbol("signal-struct");function j(t){if(t[O])return t;let e,i;if(!k(t))throw Error("Only array or object states are supported");e={},i={};for(let r in t)i[r]=A(e,r,t[r]);return Object.defineProperty(e,O,{configurable:!1,enumerable:!1,value:!0}),Object.seal(e),e}function A(t,e,i){let r,n=w(i)?i:k(i)?l(j(i)):l((r=(o=i)&&!!(o[Symbol.observable]||o[Symbol.asyncIterator]||o.call&&o.set||o.subscribe||o.then))?void 0:i);var o,s,f,a,u,h,v;return r&&(f=t=>n.value=t,(s=i)&&(v=(s[Symbol.observable]?.()||s).subscribe?.(f,a,undefined),h=v&&(()=>v.unsubscribe?.())||s.set&&s.call?.(u,f)||(s.then?.((t=>{!u&&f(t)}),a)||(async t=>{try{for await(t of s){if(u)return;f(t)}}catch(t){}})())&&(t=>u=1),x.register(s,h))),Object.defineProperty(t,e,{get:()=>n.value,set:w(i)?t=>n.value=t:k(i)?t=>t?Object.assign(n.value,t):n.value=t:t=>n.value=t,enumerable:!0,configurable:!1}),n}function k(t){return t&&t.constructor===Object}var N=new WeakMap;function $(t,e){if(!t.children)return;if(N.has(t))return N.get(t);e||={};const i=j(e),r=t=>{let e,n;if(t.attributes)for(let r=0;r<t.attributes.length;){let o=t.attributes[r];if(":"===o.name[0]){if(e=E[o.name]||E.default,t.removeAttribute(o.name),n=!1===e(t,o.value,i,o.name.slice(1)))break}else r++}if(!n)for(let e of t.children)r(e)};return r(t),N.set(t,i),i}var E={},U=(t,e,i)=>{e.startsWith("on")&&(e=e.toLowerCase()),t[e]!==i&&(t[e]=i),!1===i||null==i?t.removeAttribute(e):"function"!=typeof i&&t.setAttribute(C(e),!0===i?"":"number"==typeof i||"string"==typeof i?i:"class"===e?(Array.isArray(i)?i:Object.entries(i).map((([t,e])=>e?t:""))).filter(Boolean).join(" "):"style"===e?Object.entries(i).map((([t,e])=>`${t}: ${e}`)).join(";"):"")},W=document.createElement("div"),C=t=>{W.dataset[t]="";let e=W.attributes[0].name.slice(5);return delete W.dataset[t],e},B=(t,e,i,r=null)=>{let n,o,s,f=0,a=i.length,u=e.length,{remove:l,same:h,insert:v,replace:c}=B;for(;f<a&&f<u&&h(e[f],i[f]);)f++;for(;f<a&&f<u&&h(i[a-1],e[u-1]);)r=i[(--u,--a)];if(f==u)for(;f<a;)v(r,i[f++],t);else{for(n=e[f];f<a;)s=i[f++],o=n?n.nextSibling:r,h(n,s)?n=o:f<a&&h(i[f],o)?(c(n,s,t),n=o):v(n,s,t);for(;!h(n,r);)o=n.nextSibling,l(n,t),n=o}return i};B.same=(t,e)=>t==e,B.replace=(t,e,i)=>i.replaceChild(e,t),B.insert=(t,e,i)=>i.insertBefore(e,t),B.remove=(t,e)=>e.removeChild(t);var P=B,L={},M={},T={},F=t=>null===t?M:void 0===t?T:"number"==typeof t||t instanceof Number?L[t]||(L[t]=new Number(t)):"string"==typeof t||t instanceof String?L[t]||(L[t]=new String(t)):"boolean"==typeof t||t instanceof Boolean?L[t]||(L[t]=new Boolean(t)):t;E[":with"]=(t,i,r)=>{let n=R(i,"with",r);const s=p((()=>Object.assign({},r,n(r))));let f=$(t,s.value);S(((t=s.value)=>function(t){if(o>0)return t();o++;try{return t()}finally{e()}}((()=>Object.assign(f,t)))))},E[":if"]=(t,e,i)=>{let r=document.createTextNode(""),n=[R(e,":if",i)],o=[t],s=t;for(;(s=t.nextElementSibling)&&s.hasAttribute(":else");)s.removeAttribute(":else"),(e=s.getAttribute(":if"))?(s.removeAttribute(":if"),s.remove(),o.push(s),n.push(R(e,":else :if",i))):(s.remove(),o.push(s),n.push((()=>1)));t.replaceWith(s=r);let f=p((()=>n.findIndex((t=>t(i)))));return S(((t=f.value)=>o[t]!=s&&((s[I]||s).replaceWith(s=o[t]||r),$(s,i)))),!1};var I=Symbol(":each");E[":each"]=(t,e,r)=>{let n=function(t){let e=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,i=t.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!i)return;let r={};r.items=i[2].trim();let n=i[1].replace(/^\s*\(|\)\s*$/g,"").trim(),o=n.match(e);return o?(r.item=n.replace(e,"").trim(),r.index=o[1].trim()):r.item=n,r}(e);if(!n)return q(new Error,e);const o=R(n.items,":each",r),s=t[I]=document.createTextNode("");t.replaceWith(s);const f=p((()=>{let t=o(r);return"number"==typeof t?Array.from({length:t},((t,e)=>e+1)):t})),a=new WeakMap,u=new WeakMap;let l=[];return S(((e=f.value)=>{e||(e=[]);let o=[],h=[];for(let s of e){let e=F(s),f=u.get(e);if(f||(f=t.cloneNode(!0),u.set(e,f)),o.push(f),!a.has(e)){let t=Object.create(r);t[n.item]=s,n.index&&(t[n.index]=i),a.set(e,t)}h.push(a.get(e))}P(s.parentNode,l,o,s),l=o;for(let t=0;t<o.length;t++)$(o[t],h[t])})),!1},E.default=(t,e,i,r)=>{let n=R(e,":"+r,i);S((()=>{return e=n(i),U(t,r,e);var e}))},E[":aria"]=(t,e,i)=>{let r=R(e,":aria",i);S((()=>(e=>{for(let i in e)U(t,"aria"+i[0].toUpperCase()+i.slice(1),null==e[i]?null:e[i]+"")})(r(i))))},E[":data"]=(t,e,i)=>{let r=R(e,":data",i);const n=p((()=>r(i)));S(((e=n.value)=>{for(let i in e)t.dataset[i]=e[i]}))},E[":on"]=(t,e,i)=>{let r,n=R(e,":on",i),o=p((()=>n(i)));S(((e=o.value)=>{for(let e in r)t.removeEventListener(e,r[e]);r=e;for(let e in r)t.addEventListener(e,r[e])}))},E[":"]=(t,e,i)=>{let r=R(e,":",i);S((()=>(e=>{if(e)for(let i in e)U(t,i,e[i])})(r(i))))},E[":text"]=(t,e,i)=>{let r=R(e,":text",i);S((()=>{return e=r(i),void(t.textContent=null==e?"":e);var e}))},E[":value"]=(t,e,i)=>{let r=R(e,":in",i),[n,o]=(t=>["checkbox"===t.type?()=>t.checked:()=>t.value,"text"===t.type||""===t.type?e=>t.value=null==e?"":e:"checkbox"===t.type?e=>(t.value=e?"on":"",U(t,"checked",e)):"select-one"===t.type?e=>([...t.options].map((t=>t.removeAttribute("selected"))),t.value=e,t.selectedOptions[0]?.setAttribute("selected","")):e=>t.value=e])(t);S((()=>{return e=r(i),U(t,"value",e),void o(e);var e}))};var z={};function R(t,e,i){if(z[t])return z[t];let r,n=/^[\n\s]*if.*\(.*\)/.test(t)||/^(let|const)\s/.test(t)?`(() => { ${t} })()`:t;try{r=new Function(["scope"],`let result; with (scope) { result = ${n} }; return result;`)}catch(r){return q(r,t,e,i)}return z[t]=n=>{let o;try{o=r(n)}catch(r){return q(r,t,e,i)}return o}}function q(t,e,i,r){Object.assign(t,{expression:e}),console.warn(`∴sprae: ${t.message}\n\n${i}=${e?`"${e}"\n\n`:""}`,r),setTimeout((()=>{throw t}),0)}var D=$;export{D as default,E as directives};
1
+ function t(){throw new Error("Cycle detected")}function e(){if(o>1)o--;else{for(var t,e=!1;void 0!==n;){var i=n;for(n=void 0,s++;void 0!==i;){var r=i.o;if(i.o=void 0,i.f&=-3,!(8&i.f)&&h(i))try{i.c()}catch(i){e||(t=i,e=!0)}i=r}}if(s=0,o--,e)throw t}}function i(t){if(o>0)return t();o++;try{return t()}finally{e()}}var r=void 0,n=void 0,o=0,s=0,a=0;function f(t){if(void 0!==r){var e=t.n;if(void 0===e||e.t!==r)return r.s=e={i:0,S:t,p:void 0,n:r.s,t:r,e:void 0,x:void 0,r:e},t.n=e,32&r.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.p&&(e.p.n=e.n,void 0!==e.n&&(e.n.p=e.p),e.p=void 0,e.n=r.s,r.s.p=e,r.s=e),e}}function u(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function l(t){return new u(t)}function h(t){for(var e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return!0;return!1}function c(t){for(var e=t.s;void 0!==e;e=e.n){var i=e.S.n;void 0!==i&&(e.r=i),e.S.n=e,e.i=-1}}function v(t){for(var e=t.s,i=void 0;void 0!==e;){var r=e.n;-1===e.i?(e.S.U(e),e.n=void 0):(void 0!==i&&(i.p=e),e.p=void 0,e.n=i,i=e),e.S.n=e.r,void 0!==e.r&&(e.r=void 0),e=r}t.s=i}function d(t){u.call(this,void 0),this.x=t,this.s=void 0,this.g=a-1,this.f=4}function p(t){return new d(t)}function b(t){var i=t.u;if(t.u=void 0,"function"==typeof i){o++;var n=r;r=void 0;try{i()}catch(e){throw t.f&=-2,t.f|=8,y(t),e}finally{r=n,e()}}}function y(t){for(var e=t.s;void 0!==e;e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,b(t)}function m(t){if(r!==this)throw new Error("Out-of-order effect");v(this),r=t,this.f&=-2,8&this.f&&y(this),e()}function g(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function S(t){var e=new g(t);return e.c(),e.d.bind(e)}u.prototype.h=function(){return!0},u.prototype.S=function(t){this.t!==t&&void 0===t.e&&(t.x=this.t,void 0!==this.t&&(this.t.e=t),this.t=t)},u.prototype.U=function(t){var e=t.e,i=t.x;void 0!==e&&(e.x=i,t.e=void 0),void 0!==i&&(i.e=e,t.x=void 0),t===this.t&&(this.t=i)},u.prototype.subscribe=function(t){var e=this;return S((function(){var i=e.value,r=32&this.f;this.f&=-33;try{t(i)}finally{this.f|=r}}))},u.prototype.valueOf=function(){return this.value},u.prototype.toString=function(){return this.value+""},u.prototype.peek=function(){return this.v},Object.defineProperty(u.prototype,"value",{get:function(){var t=f(this);return void 0!==t&&(t.i=this.i),this.v},set:function(i){if(i!==this.v){s>100&&t(),this.v=i,this.i++,a++,o++;try{for(var r=this.t;void 0!==r;r=r.x)r.t.N()}finally{e()}}}}),(d.prototype=new u).h=function(){if(this.f&=-3,1&this.f)return!1;if(32==(36&this.f))return!0;if(this.f&=-5,this.g===a)return!0;if(this.g=a,this.f|=1,this.i>0&&!h(this))return this.f&=-2,!0;var t=r;try{c(this),r=this;var e=this.x();(16&this.f||this.v!==e||0===this.i)&&(this.v=e,this.f&=-17,this.i++)}catch(t){this.v=t,this.f|=16,this.i++}return r=t,v(this),this.f&=-2,!0},d.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(var e=this.s;void 0!==e;e=e.n)e.S.S(e)}u.prototype.S.call(this,t)},d.prototype.U=function(t){if(u.prototype.U.call(this,t),void 0===this.t){this.f&=-33;for(var e=this.s;void 0!==e;e=e.n)e.S.U(e)}},d.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var t=this.t;void 0!==t;t=t.x)t.t.N()}},d.prototype.peek=function(){if(this.h()||t(),16&this.f)throw this.v;return this.v},Object.defineProperty(d.prototype,"value",{get:function(){1&this.f&&t();var e=f(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),g.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},g.prototype.S=function(){1&this.f&&t(),this.f|=1,this.f&=-9,b(this),c(this),o++;var e=r;return r=this,m.bind(this,e)},g.prototype.N=function(){2&this.f||(this.f|=2,this.o=n,n=this)},g.prototype.d=function(){this.f|=8,1&this.f||y(this)},Symbol.observable||=Symbol("observable");var x=new FinalizationRegistry((t=>t.call?.())),w=t=>t&&t.peek,A=Symbol("signal-struct");function O(t){if((e=t)&&e[A])return t;var e;let i,r;if(k(t)){i={},r={};for(let e in t)r[e]=j(i,e,t[e]);return Object.defineProperty(i,A,{configurable:!1,enumerable:!1,value:!0}),Object.seal(i),i}return Array.isArray(t)?t.map((t=>O(t))):t}function j(t,e,i){let r,n=w(i)?i:k(i)||Array.isArray(i)?l(O(i)):l((r=(o=i)&&!!(o[Symbol.observable]||o[Symbol.asyncIterator]||o.call&&o.set||o.subscribe||o.then))?void 0:i);var o,s,a,f,u,h,c;return r&&(a=t=>n.value=t,(s=i)&&(c=(s[Symbol.observable]?.()||s).subscribe?.(a,f,undefined),h=c&&(()=>c.unsubscribe?.())||s.set&&s.call?.(u,a)||(s.then?.((t=>{!u&&a(t)}),f)||(async t=>{try{for await(t of s){if(u)return;a(t)}}catch(t){}})())&&(t=>u=1),x.register(s,h))),Object.defineProperty(t,e,{get:()=>n.value,set:!w(i)&&k(i)?t=>t?Object.assign(n.value,t):n.value=O(t):t=>n.value=O(t),enumerable:!0,configurable:!1}),n}function k(t){return t&&t.constructor===Object}var N=(t,e,i)=>{e.startsWith("on")&&(e=e.toLowerCase()),t[e]!==i&&(t[e]=i),!1===i||null==i?t.removeAttribute(e):"function"!=typeof i&&t.setAttribute(E(e),!0===i?"":"number"==typeof i||"string"==typeof i?i:"class"===e?(Array.isArray(i)?i:Object.entries(i).map((([t,e])=>e?t:""))).filter(Boolean).join(" "):"style"===e?Object.entries(i).map((([t,e])=>`${t}: ${e}`)).join(";"):"")},$=document.createElement("div"),E=t=>{$.dataset[t]="";let e=$.attributes[0].name.slice(5);return delete $.dataset[t],e},U=(t,e,i,r=null)=>{let n,o,s,a=0,f=i.length,u=e.length,{remove:l,same:h,insert:c,replace:v}=U;for(;a<f&&a<u&&h(e[a],i[a]);)a++;for(;a<f&&a<u&&h(i[f-1],e[u-1]);)r=i[(--u,--f)];if(a==u)for(;a<f;)c(r,i[a++],t);else{for(n=e[a];a<f;)s=i[a++],o=n?n.nextSibling:r,h(n,s)?n=o:a<f&&h(i[a],o)?(v(n,s,t),n=o):c(n,s,t);for(;!h(n,r);)o=n.nextSibling,l(n,t),n=o}return i};U.same=(t,e)=>t==e,U.replace=(t,e,i)=>i.replaceChild(e,t),U.insert=(t,e,i)=>i.insertBefore(e,t),U.remove=(t,e)=>e.removeChild(t);var W=U,C={},B={},P={},L=(t,e,i,r)=>{let n=z(e,":"+r,i);S((()=>{return e=n(i),N(t,r,e);var e}))},M={},T=Symbol(":each"),F=Symbol(":ref");M[":with"]=(t,e,r)=>{let n=z(e,"with",r);const o=p((()=>Object.assign({},r,n(r))));let s=D(t,o.value);return S(((t=o.value)=>i((()=>Object.assign(s,t))))),!1},M[":ref"]=(t,e,i)=>t.hasAttribute(":each")?t[F]=e:(D(t,Object.assign(Object.create(i),{[e]:t})),!1),M[":if"]=(t,e,i)=>{let r=document.createTextNode(""),n=[z(e,":if",i)],o=[t],s=t;for(;(s=t.nextElementSibling)&&s.hasAttribute(":else");)s.removeAttribute(":else"),(e=s.getAttribute(":if"))?(s.removeAttribute(":if"),s.remove(),o.push(s),n.push(z(e,":else :if",i))):(s.remove(),o.push(s),n.push((()=>1)));t.replaceWith(s=r);let a=p((()=>n.findIndex((t=>t(i)))));return S(((t=a.value)=>o[t]!=s&&((s[T]||s).replaceWith(s=o[t]||r),D(s,i)))),!1},M[":each"]=(t,e,i)=>{let r=function(t){let e=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,i=t.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!i)return;let r={};r.items=i[2].trim();let n=i[1].replace(/^\s*\(|\)\s*$/g,"").trim(),o=n.match(e);return o?(r.item=n.replace(e,"").trim(),r.index=o[1].trim()):r.item=n,r}(e);if(!r)return R(new Error,e);const n=z(r.items,":each",i),o=t[T]=document.createTextNode("");t.replaceWith(o);const s=p((()=>{let t=n(i);return t?"number"==typeof t?Array.from({length:t},((t,e)=>[e,e+1])):t.constructor===Object?Object.entries(t):Array.isArray(t)?t.map(((t,e)=>[e+1,t])):void R(Error("Bad list value"),r.items,":each",t):[]})),a=new WeakMap,f=new WeakMap;let u=[];return S(((e=s.value)=>{let n=[],l=[];for(let[o,s]of e){let e=null===(h=s)?B:void 0===h?P:"number"==typeof h||h instanceof Number?C[h]||(C[h]=new Number(h)):"string"==typeof h||h instanceof String?C[h]||(C[h]=new String(h)):"boolean"==typeof h||h instanceof Boolean?C[h]||(C[h]=new Boolean(h)):h,u=f.get(e);if(u||(u=t.cloneNode(!0),f.set(e,u)),n.push(u),!a.has(e)){let n=Object.create(i);n[r.item]=s,r.index&&(n[r.index]=o),t[F]&&(n[t[F]]=u),a.set(e,n)}l.push(a.get(e))}var h;W(o.parentNode,u,n,o),u=n;for(let t=0;t<n.length;t++)D(n[t],l[t])})),!1},M[":id"]=(t,e,i)=>{let r=z(e,":id",i);S((()=>{return e=r(i),t.id=e||0===e?e:"";var e}))},M[":"]=(t,e,i)=>{let r=z(e,":",i);S((()=>(e=>{if(e)for(let i in e)N(t,i,e[i])})(r(i))))},M[":text"]=(t,e,i)=>{let r=z(e,":text",i);S((()=>{return e=r(i),void(t.textContent=null==e?"":e);var e}))},M[":value"]=(t,e,i)=>{let r=z(e,":in",i),[n,o]=(t=>["checkbox"===t.type?()=>t.checked:()=>t.value,"text"===t.type||""===t.type?e=>t.value=null==e?"":e:"checkbox"===t.type?e=>(t.value=e?"on":"",N(t,"checked",e)):"select-one"===t.type?e=>([...t.options].map((t=>t.removeAttribute("selected"))),t.value=e,t.selectedOptions[0]?.setAttribute("selected","")):e=>t.value=e])(t);S((()=>{return e=r(i),N(t,"value",e),void o(e);var e}))},M[":on"]=(t,e,i)=>{let r,n=z(e,":on",i),o=p((()=>n(i)));S(((e=o.value)=>{for(let e in r)t.removeEventListener(e,r[e]);r=e;for(let e in r)t.addEventListener(e,r[e])}))},M[":data"]=(t,e,i)=>{let r=z(e,":data",i);const n=p((()=>r(i)));S(((e=n.value)=>{for(let i in e)t.dataset[i]=e[i]}))},M[":aria"]=(t,e,i)=>{let r=z(e,":aria",i);S((()=>(e=>{for(let i in e)N(t,"aria"+i[0].toUpperCase()+i.slice(1),null==e[i]?null:e[i]+"")})(r(i))))};var I={};function z(t,e,i){if(I[t])return I[t];let r,n=/^[\n\s]*if.*\(.*\)/.test(t)||/^(let|const)\s/.test(t)?`(() => { ${t} })()`:t;try{r=new Function(`let result; with (arguments[0]) { result = (${n}) }; return result;`)}catch(r){return R(r,t,e,i)}return I[t]=n=>{let o;try{o=r(n)}catch(r){return R(r,t,e,i)}return o}}function R(t,e,i,r){Object.assign(t,{expression:e}),console.warn(`∴sprae: ${t.message}\n\n${i}=${e?`"${e}"\n\n`:""}`,r),setTimeout((()=>{throw t}),0)}var q=new WeakMap;function D(t,e){if(!t.children)return;if(q.has(t))return q.get(t);e||={};const i=O(e),r=t=>{let e,n;if(t.attributes){for(let r in M)if((n=t.attributes[r])&&(e=M[r],t.removeAttribute(r),!1===e(t,n.value,i)))return;for(let e=0;e<t.attributes.length;){let r=t.attributes[e];if(":"===r.name[0]){if(t.removeAttribute(r.name),!1===L(t,r.value,i,r.name.slice(1)))return}else e++}}for(let e of t.children)r(e)};return r(t),q.set(t,i),i}var G=D;export{i as batch,p as computed,G as default,S as effect,l as signal};
package/src/core.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import signalStruct from 'signal-struct';
2
+ import defaultDirective, { directives } from './directives.js';
2
3
 
3
4
  // sprae element: apply directives
4
5
  const memo = new WeakMap
@@ -12,27 +13,34 @@ export default function sprae(container, values) {
12
13
 
13
14
  // init directives on element
14
15
  const init = (el) => {
15
- let dir, stop
16
+ let dir, attr
17
+
16
18
  if (el.attributes) {
19
+ // directives must be initialized in order
20
+ for (let name in directives) {
21
+ if (attr = el.attributes[name]) {
22
+ dir = directives[name]
23
+ el.removeAttribute(name)
24
+ if (dir(el, attr.value, state) === false) return
25
+ }
26
+ }
27
+
17
28
  for (let i = 0; i < el.attributes.length;) {
18
29
  let attr = el.attributes[i]
19
30
  if (attr.name[0]===':') {
20
- dir = directives[attr.name] || directives.default
21
31
  el.removeAttribute(attr.name)
22
- if (stop = (dir(el, attr.value, state, attr.name.slice(1))===false)) break
32
+ if (defaultDirective(el, attr.value, state, attr.name.slice(1)) === false) return
23
33
  }
24
34
  else i++
25
35
  }
26
36
  }
27
- if (!stop) for (let child of el.children) init(child)
37
+
38
+ for (let child of el.children) init(child)
28
39
  }
40
+
29
41
  init(container)
30
42
 
31
43
  memo.set(container, state);
32
44
 
33
45
  return state;
34
46
  }
35
-
36
-
37
- // dict of directives
38
- export const directives = {}
package/src/directives.js CHANGED
@@ -1,11 +1,24 @@
1
1
  // directives & parsing
2
- import sprae, { directives } from './core.js'
2
+ import sprae from './core.js'
3
3
  import { prop, input } from 'element-props'
4
- // import { effect, computed, batch } from 'usignal'
4
+ // import { effect, computed, batch } from 'usignal/sync'
5
5
  import { effect, computed, batch } from '@preact/signals-core'
6
6
  import swap from 'swapdom'
7
7
  import p from 'primitive-pool'
8
8
 
9
+
10
+ // any-prop directives
11
+ export default (el, expr, state, name) => {
12
+ let evaluate = parseExpr(expr, ':'+name, state)
13
+ const update = value => prop(el, name, value)
14
+ effect(() => update(evaluate(state)))
15
+ }
16
+
17
+ // reserved directives - order matters!
18
+ export const directives = {}
19
+
20
+ const _each = Symbol(':each'), _ref = Symbol(':ref')
21
+
9
22
  directives[':with'] = (el, expr, rootState) => {
10
23
  let evaluate = parseExpr(expr, 'with', rootState)
11
24
 
@@ -13,7 +26,16 @@ directives[':with'] = (el, expr, rootState) => {
13
26
  // we bind updating
14
27
  const params = computed(() => Object.assign({}, rootState, evaluate(rootState)))
15
28
  let state = sprae(el, params.value)
16
- effect((values=params.value) => batch(()=>Object.assign(state, values)))
29
+ effect((values=params.value) => batch(() => Object.assign(state, values)))
30
+ return false
31
+ }
32
+
33
+ directives[':ref'] = (el, expr, state) => {
34
+ // make sure :ref is initialized after :each
35
+ if (el.hasAttribute(':each')) return el[_ref] = expr;
36
+
37
+ sprae(el, Object.assign(Object.create(state), {[expr]: el}))
38
+ return false
17
39
  }
18
40
 
19
41
  directives[':if'] = (el, expr, state) => {
@@ -38,12 +60,11 @@ directives[':if'] = (el, expr, state) => {
38
60
  el.replaceWith(cur = holder)
39
61
  let idx = computed(() => clauses.findIndex(f => f(state)))
40
62
  // NOTE: it lazily initializes elements on insertion, it's safe to sprae multiple times
41
- effect((i=idx.value) => (els[i] != cur && ((cur[_eachHolder]||cur).replaceWith(cur = els[i] || holder), sprae(cur, state))))
63
+ effect((i=idx.value) => (els[i] != cur && ((cur[_each]||cur).replaceWith(cur = els[i] || holder), sprae(cur, state))))
42
64
 
43
65
  return false
44
66
  }
45
67
 
46
- const _eachHolder = Symbol(':each')
47
68
  directives[':each'] = (tpl, expr, state) => {
48
69
  let each = parseForExpression(expr);
49
70
  if (!each) return exprError(new Error, expr);
@@ -51,14 +72,17 @@ directives[':each'] = (tpl, expr, state) => {
51
72
  const getItems = parseExpr(each.items, ':each', state);
52
73
 
53
74
  // FIXME: make sure no memory leak here
54
- // we need holder to be able :if replace it instead of tpl for combined case
55
- const holder = tpl[_eachHolder] = document.createTextNode('')
75
+ // we need :if to be able to replace holder instead of tpl for :if :each case
76
+ const holder = tpl[_each] = document.createTextNode('')
56
77
  tpl.replaceWith(holder)
57
78
 
58
79
  const items = computed(()=>{
59
80
  let list = getItems(state)
60
- if (typeof list === 'number') return Array.from({length: list}, (_, i)=>i+1)
61
- return list
81
+ if (!list) return []
82
+ if (typeof list === 'number') return Array.from({length: list}, (_, i)=>[i, i+1])
83
+ if (list.constructor === Object) return Object.entries(list)
84
+ if (Array.isArray(list)) return list.map((item,i) => [i+1, item])
85
+ exprError(Error('Bad list value'), each.items, ':each', list)
62
86
  })
63
87
 
64
88
  // stores scope per data item
@@ -67,26 +91,27 @@ directives[':each'] = (tpl, expr, state) => {
67
91
  const itemEls = new WeakMap()
68
92
  let curEls = []
69
93
  effect((list=items.value) => {
70
- if (!list) list = []
71
94
  // collect elements/scopes for items
72
95
  let newEls = [], elScopes = []
73
96
 
74
- for (let item of list) {
75
- let key = p(item)
76
- let el = itemEls.get(key)
97
+ for (let [idx, item] of list) {
98
+ let itemKey = p(item)
99
+ let el = itemEls.get(itemKey)
77
100
  if (!el) {
78
101
  el = tpl.cloneNode(true)
79
- itemEls.set(key, el)
102
+ itemEls.set(itemKey, el)
80
103
  }
81
104
  newEls.push(el)
82
105
 
83
- if (!scopes.has(key)) {
106
+ if (!scopes.has(itemKey)) {
84
107
  let scope = Object.create(state)
85
108
  scope[each.item] = item
86
- if (each.index) scope[each.index] = i;
87
- scopes.set(key, scope)
109
+ if (each.index) scope[each.index] = idx;
110
+ // provide ref, if indicated
111
+ if (tpl[_ref]) scope[tpl[_ref]] = el
112
+ scopes.set(itemKey, scope)
88
113
  }
89
- elScopes.push(scopes.get(key))
114
+ elScopes.push(scopes.get(itemKey))
90
115
  }
91
116
 
92
117
  // swap is really fast & tiny
@@ -126,39 +151,10 @@ function parseForExpression(expression) {
126
151
  return res
127
152
  }
128
153
 
129
-
130
- // common-setter directives
131
- directives['default'] = (el, expr, state, name) => {
132
- let evaluate = parseExpr(expr, ':'+name, state)
133
- const update = value => prop(el, name, value)
134
- effect(() => update(evaluate(state)))
135
- }
136
-
137
- directives[':aria'] = (el, expr, state) => {
138
- let evaluate = parseExpr(expr, ':aria', state)
139
- const update = (value) => {
140
- for (let key in value) prop(el, 'aria'+key[0].toUpperCase()+key.slice(1), value[key] == null ? null : value[key] + '');
141
- }
142
- effect(() => update(evaluate(state)))
143
- }
144
-
145
- directives[':data'] = (el, expr, state) => {
146
- let evaluate = parseExpr(expr, ':data', state)
147
- const value = computed(() => evaluate(state))
148
- effect((v=value.value) => {
149
- for (let key in v) el.dataset[key] = v[key];
150
- })
151
- }
152
-
153
- directives[':on'] = (el, expr, state) => {
154
- let evaluate = parseExpr(expr, ':on', state)
155
- let listeners = computed(() => evaluate(state))
156
- let prevListeners
157
- effect((values=listeners.value) => {
158
- for (let evt in prevListeners) el.removeEventListener(evt, prevListeners[evt]);
159
- prevListeners = values;
160
- for (let evt in prevListeners) el.addEventListener(evt, prevListeners[evt]);
161
- })
154
+ directives[':id'] = (el, expr, state) => {
155
+ let evaluate = parseExpr(expr, ':id', state)
156
+ const update = v => el.id = v || v === 0 ? v : ''
157
+ effect(()=>update(evaluate(state)))
162
158
  }
163
159
 
164
160
  directives[':'] = (el, expr, state) => {
@@ -193,6 +189,34 @@ directives[':value'] = (el, expr, state) => {
193
189
  effect(()=>update(evaluate(state)))
194
190
  }
195
191
 
192
+ directives[':on'] = (el, expr, state) => {
193
+ let evaluate = parseExpr(expr, ':on', state)
194
+ let listeners = computed(() => evaluate(state))
195
+ let prevListeners
196
+ effect((values=listeners.value) => {
197
+ for (let evt in prevListeners) el.removeEventListener(evt, prevListeners[evt]);
198
+ prevListeners = values;
199
+ for (let evt in prevListeners) el.addEventListener(evt, prevListeners[evt]);
200
+ })
201
+ }
202
+
203
+ directives[':data'] = (el, expr, state) => {
204
+ let evaluate = parseExpr(expr, ':data', state)
205
+ const value = computed(() => evaluate(state))
206
+ effect((v=value.value) => {
207
+ for (let key in v) el.dataset[key] = v[key];
208
+ })
209
+ }
210
+
211
+ directives[':aria'] = (el, expr, state) => {
212
+ let evaluate = parseExpr(expr, ':aria', state)
213
+ const update = (value) => {
214
+ for (let key in value) prop(el, 'aria'+key[0].toUpperCase()+key.slice(1), value[key] == null ? null : value[key] + '');
215
+ }
216
+ effect(() => update(evaluate(state)))
217
+ }
218
+
219
+
196
220
  let evaluatorMemo = {}
197
221
 
198
222
  // borrowed from alpine: https://github.com/alpinejs/alpine/blob/main/packages/alpinejs/src/evaluator.js#L61
@@ -214,7 +238,7 @@ function parseExpr(expression, dir, scope) {
214
238
  // guard static-time eval errors
215
239
  let evaluate
216
240
  try {
217
- evaluate = new Function(['scope'], `let result; with (scope) { result = ${rightSideSafeExpression} }; return result;`)
241
+ evaluate = new Function( `let result; with (arguments[0]) { result = (${rightSideSafeExpression}) }; return result;`)
218
242
  } catch ( e ) {
219
243
  return exprError(e, expression, dir, scope)
220
244
  }
package/src/index.js CHANGED
@@ -2,7 +2,7 @@ import sprae from './core.js';
2
2
  import './directives.js';
3
3
 
4
4
  export default sprae;
5
- export * from './core.js';
5
+ export { signal, computed, batch, effect } from '@preact/signals-core';
6
6
 
7
7
  // autoinit
8
8
  // NOTE: abandoning for now, since requires a separate non-module JS entry, until use-case appears
package/test/index.html CHANGED
@@ -19,7 +19,7 @@
19
19
  "preact": "../node_modules/preact/dist/preact.mjs",
20
20
  "preact/hooks": "../node_modules/preact/hooks/dist/hooks.mjs",
21
21
  "@preact/signals-core": "../node_modules/@preact/signals-core/dist/signals-core.mjs",
22
- "usignal": "../node_modules/usignal/esm/sync.js"
22
+ "usignal/sync": "../node_modules/usignal/esm/sync.js"
23
23
  }
24
24
  }
25
25
  </script>
package/test/test.js CHANGED
@@ -1,4 +1,4 @@
1
- // import { signal } from 'usignal'
1
+ // import { signal } from 'usignal/sync'
2
2
  import { signal } from '@preact/signals-core'
3
3
  import test, {is, any, throws} from 'tst'
4
4
  import {tick, time} from 'wait-please'
@@ -171,7 +171,7 @@ test('conditions: reactive values', async () => {
171
171
  })
172
172
 
173
173
 
174
- test('each: base', async () => {
174
+ test('each: array', async () => {
175
175
  // FIXME: in some conspicuous reason jsdom fails to update text nodes somehow
176
176
  let el = h`<p>
177
177
  <span :each="a in b" :text="a"></span>
@@ -189,6 +189,24 @@ test('each: base', async () => {
189
189
  is(el.innerHTML, '')
190
190
  })
191
191
 
192
+ test('each: object', async () => {
193
+ // FIXME: in some conspicuous reason jsdom fails to update text nodes somehow
194
+ let el = h`<p>
195
+ <span :each="x,key in b" :text="[key,x]"></span>
196
+ </p>`
197
+
198
+ const params = sprae(el, { b: null })
199
+
200
+ is(el.innerHTML, '')
201
+ console.log('set 1,2')
202
+ params.b = { x:1, y:2 }
203
+ is(el.innerHTML, '<span>x,1</span><span>y,2</span>')
204
+ params.b = []
205
+ is(el.innerHTML, '')
206
+ params.b = null
207
+ is(el.innerHTML, '')
208
+ })
209
+
192
210
  test('each: loop within loop', async () => {
193
211
  let el = h`<p>
194
212
  <x :each="b in c"><y :each="a in b" :text="a"></y></x>
@@ -197,7 +215,6 @@ test('each: loop within loop', async () => {
197
215
  const params = sprae(el, { c: [[1,2], [3,4]] })
198
216
 
199
217
  is(el.innerHTML, '<x><y>1</y><y>2</y></x><x><y>3</y><y>4</y></x>')
200
- // console.log('set 1,2')
201
218
  params.c = [[5,6], [3,4]]
202
219
  is(el.innerHTML, '<x><y>5</y><y>6</y></x><x><y>3</y><y>4</y></x>')
203
220
  // params.c[1] = [7,8]
@@ -228,6 +245,9 @@ test('each: reactive values', async () => {
228
245
  })
229
246
 
230
247
  test('each: loop with condition', async () => {
248
+ // NOTE: there doesn't seem to be much value in exactly that
249
+ // also it creates confusion with :else directive
250
+ // prohibitin that allows in-order directives init
231
251
  let el = h`<p>
232
252
  <span :each="a in b" :text="a" :if="c"></span>
233
253
  </p>`
@@ -368,7 +388,23 @@ test('with: writes to state', () => {
368
388
  is(a.innerHTML, `<y>3</y>`)
369
389
  })
370
390
 
371
- test('reactives', async () => {
391
+ test('ref: base', () => {
392
+ let a = h`<a :ref="a" :init="log.push(a), null" :text="b"></a>`
393
+ let state = sprae(a, {log:[], b:1})
394
+ is(state.log[0], a)
395
+ is(a.outerHTML, `<a>1</a>`)
396
+ state.b = 2
397
+ is(a.outerHTML, `<a>2</a>`)
398
+ })
399
+
400
+ test('ref with each', () => {
401
+ let a = h`<y><x :ref="x" :each="item in items" :text="log.push(x), item"/></y>`
402
+ let state = sprae(a, {log: [], items: [1,2]})
403
+ is(a.innerHTML, `<x>1</x><x>2</x>`)
404
+ is(state.log, [...a.children])
405
+ })
406
+
407
+ test('reactive values', async () => {
372
408
  let a = new Promise((ok) => setTimeout(() => ok(2), 10))
373
409
 
374
410
  let el = h`<x :text="a">1</x>`
@@ -377,4 +413,10 @@ test('reactives', async () => {
377
413
 
378
414
  await time(20)
379
415
  is(el.outerHTML, `<x>2</x>`)
416
+ })
417
+
418
+ test('scope directives must come first', async () => {
419
+ let a = h`<x :text="y" :with="{y:1}" :ref="x"></x>`
420
+ sprae(a, {})
421
+ is(a.outerHTML, `<x>1</x>`)
380
422
  })
@@ -1,53 +0,0 @@
1
- import sprae, { directive, exprError, parseExpr } from '../core.js'
2
-
3
- directive(':each', (el, expr) => {
4
- let each = parseForExpression(expr);
5
- if (!each) return exprError(new Error, expr);
6
-
7
- const getItems = parseExpr(each.items);
8
-
9
- const holder = new Text
10
- el.replaceWith(holder)
11
-
12
- // FIXME: make sure no memory leak here
13
- // FIXME: there can DOM swapper be used instead
14
- let els = [];
15
- return state => {
16
- els.forEach(el => el.remove()); els = [];
17
- let items = getItems(state);
18
- if (typeof items === 'number') items = Array.from({length: items}, (item, i)=>i+1)
19
- items?.forEach((item,i) => {
20
- const scope = {...state};
21
- scope[each.item] = item;
22
- if (each.index) scope[each.index] = i;
23
- let itemEl = el.cloneNode(true);
24
- els.push(itemEl);
25
- holder.before(itemEl);
26
- sprae(itemEl, scope);
27
- });
28
- }
29
- })
30
-
31
- // This was taken AlpineJS, former VueJS 2.* core. Thanks Alpine & Vue!
32
- function parseForExpression(expression) {
33
- let forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/
34
- let stripParensRE = /^\s*\(|\)\s*$/g
35
- let forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
36
- let inMatch = expression.match(forAliasRE)
37
-
38
- if (!inMatch) return
39
-
40
- let res = {}
41
- res.items = inMatch[2].trim()
42
- let item = inMatch[1].replace(stripParensRE, '').trim()
43
- let iteratorMatch = item.match(forIteratorRE)
44
-
45
- if (iteratorMatch) {
46
- res.item = item.replace(forIteratorRE, '').trim()
47
- res.index = iteratorMatch[1].trim()
48
- } else {
49
- res.item = item
50
- }
51
-
52
- return res
53
- }