sigmx 0.1.0 → 0.2.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/README.md +54 -43
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +2 -2
- package/dist/kernel/compile.d.ts +8 -9
- package/dist/kernel/compile.js +102 -67
- package/dist/kernel/compile.js.map +2 -2
- package/dist/kernel/contracts.d.ts +12 -13
- package/dist/kernel/index.d.ts +11 -12
- package/dist/kernel/index.js +14 -12
- package/dist/kernel/index.js.map +3 -3
- package/dist/kernel/precompile.d.ts +8 -12
- package/dist/kernel/precompile.js +33 -76
- package/dist/kernel/precompile.js.map +2 -2
- package/dist/kernel/precompiled.d.ts +7 -4
- package/dist/kernel/precompiled.js +5 -5
- package/dist/kernel/precompiled.js.map +2 -2
- package/dist/kernel/reactive.d.ts +13 -11
- package/dist/kernel/reactive.js +96 -71
- package/dist/kernel/reactive.js.map +3 -3
- package/dist/kernel/runtime.js +85 -63
- package/dist/kernel/runtime.js.map +3 -3
- package/dist/kernel/scan.d.ts +2 -11
- package/dist/kernel/scan.js +26 -9
- package/dist/kernel/scan.js.map +2 -2
- package/dist/kernel/state.d.ts +5 -8
- package/dist/kernel/state.js +114 -76
- package/dist/kernel/state.js.map +2 -2
- package/dist/kernel/strict-csp.d.ts +0 -5
- package/dist/kernel/strict-csp.js +2 -2
- package/dist/kernel/strict-csp.js.map +2 -2
- package/dist/lib/casing.d.ts +4 -1
- package/dist/lib/casing.js +8 -1
- package/dist/lib/casing.js.map +2 -2
- package/dist/lib/objects.d.ts +5 -4
- package/dist/lib/objects.js +13 -5
- package/dist/lib/objects.js.map +2 -2
- package/dist/lib/schedule.d.ts +3 -5
- package/dist/lib/schedule.js +12 -10
- package/dist/lib/schedule.js.map +2 -2
- package/dist/lib/sse.d.ts +10 -1
- package/dist/lib/sse.js +32 -28
- package/dist/lib/sse.js.map +2 -2
- package/dist/plugins/def.d.ts +5 -0
- package/dist/plugins/def.js +22 -0
- package/dist/plugins/def.js.map +7 -0
- package/dist/plugins/directives/attribute-sync.js +8 -12
- package/dist/plugins/directives/attribute-sync.js.map +2 -2
- package/dist/plugins/directives/boost.d.ts +1 -1
- package/dist/plugins/directives/boost.js +34 -30
- package/dist/plugins/directives/boost.js.map +2 -2
- package/dist/plugins/directives/busy-flag.js +13 -16
- package/dist/plugins/directives/busy-flag.js.map +2 -2
- package/dist/plugins/directives/class-toggle.js +17 -16
- package/dist/plugins/directives/class-toggle.js.map +2 -2
- package/dist/plugins/directives/cloak.js +2 -7
- package/dist/plugins/directives/cloak.js.map +2 -2
- package/dist/plugins/directives/collapse.js +36 -37
- package/dist/plugins/directives/collapse.js.map +2 -2
- package/dist/plugins/directives/declare.js +5 -8
- package/dist/plugins/directives/declare.js.map +2 -2
- package/dist/plugins/directives/derive.js +9 -15
- package/dist/plugins/directives/derive.js.map +2 -2
- package/dist/plugins/directives/element-ref.js +8 -8
- package/dist/plugins/directives/element-ref.js.map +2 -2
- package/dist/plugins/directives/event-listener.js +18 -23
- package/dist/plugins/directives/event-listener.js.map +2 -2
- package/dist/plugins/directives/frame-loop.js +9 -14
- package/dist/plugins/directives/frame-loop.js.map +2 -2
- package/dist/plugins/directives/html.js +6 -7
- package/dist/plugins/directives/html.js.map +2 -2
- package/dist/plugins/directives/inline-style.js +17 -20
- package/dist/plugins/directives/inline-style.js.map +2 -2
- package/dist/plugins/directives/mask.js +19 -23
- package/dist/plugins/directives/mask.js.map +2 -2
- package/dist/plugins/directives/media-query.d.ts +4 -1
- package/dist/plugins/directives/media-query.js +13 -12
- package/dist/plugins/directives/media-query.js.map +2 -2
- package/dist/plugins/directives/on-mount.js +4 -9
- package/dist/plugins/directives/on-mount.js.map +2 -2
- package/dist/plugins/directives/patch-listener.js +24 -19
- package/dist/plugins/directives/patch-listener.js.map +2 -2
- package/dist/plugins/directives/remove-me.js +7 -8
- package/dist/plugins/directives/remove-me.js.map +2 -2
- package/dist/plugins/directives/scroll-to.d.ts +4 -1
- package/dist/plugins/directives/scroll-to.js +8 -14
- package/dist/plugins/directives/scroll-to.js.map +2 -2
- package/dist/plugins/directives/size-watch.js +7 -12
- package/dist/plugins/directives/size-watch.js.map +2 -2
- package/dist/plugins/directives/state-dump.js +6 -10
- package/dist/plugins/directives/state-dump.js.map +2 -2
- package/dist/plugins/directives/storage-sync.js +13 -9
- package/dist/plugins/directives/storage-sync.js.map +2 -2
- package/dist/plugins/directives/teleport.js +8 -14
- package/dist/plugins/directives/teleport.js.map +2 -2
- package/dist/plugins/directives/text-content.js +6 -7
- package/dist/plugins/directives/text-content.js.map +2 -2
- package/dist/plugins/directives/timer.js +7 -13
- package/dist/plugins/directives/timer.js.map +2 -2
- package/dist/plugins/directives/transition.d.ts +1 -2
- package/dist/plugins/directives/transition.js +32 -34
- package/dist/plugins/directives/transition.js.map +2 -2
- package/dist/plugins/directives/tween.d.ts +2 -2
- package/dist/plugins/directives/tween.js +34 -50
- package/dist/plugins/directives/tween.js.map +2 -2
- package/dist/plugins/directives/two-way-bind.d.ts +1 -1
- package/dist/plugins/directives/two-way-bind.js +70 -67
- package/dist/plugins/directives/two-way-bind.js.map +2 -2
- package/dist/plugins/directives/url-params.js +36 -59
- package/dist/plugins/directives/url-params.js.map +3 -3
- package/dist/plugins/directives/url-replace.js +6 -7
- package/dist/plugins/directives/url-replace.js.map +2 -2
- package/dist/plugins/directives/validity.js +6 -9
- package/dist/plugins/directives/validity.js.map +2 -2
- package/dist/plugins/directives/viewport.js +18 -23
- package/dist/plugins/directives/viewport.js.map +2 -2
- package/dist/plugins/directives/visibility.js +9 -14
- package/dist/plugins/directives/visibility.js.map +2 -2
- package/dist/plugins/directives/watch.d.ts +0 -1
- package/dist/plugins/directives/watch.js +2 -8
- package/dist/plugins/directives/watch.js.map +2 -2
- package/dist/plugins/functions/bulk-set.js +10 -7
- package/dist/plugins/functions/bulk-set.js.map +2 -2
- package/dist/plugins/functions/bulk-toggle.js +10 -7
- package/dist/plugins/functions/bulk-toggle.js.map +2 -2
- package/dist/plugins/functions/confirm.js +2 -2
- package/dist/plugins/functions/confirm.js.map +2 -2
- package/dist/plugins/functions/copy-text.js +5 -5
- package/dist/plugins/functions/copy-text.js.map +2 -2
- package/dist/plugins/functions/dispatch.js +5 -5
- package/dist/plugins/functions/dispatch.js.map +2 -2
- package/dist/plugins/functions/locale-format.d.ts +4 -1
- package/dist/plugins/functions/locale-format.js +9 -16
- package/dist/plugins/functions/locale-format.js.map +2 -2
- package/dist/plugins/functions/range-map.js +6 -6
- package/dist/plugins/functions/range-map.js.map +2 -2
- package/dist/plugins/functions/request.d.ts +7 -3
- package/dist/plugins/functions/request.js +85 -80
- package/dist/plugins/functions/request.js.map +2 -2
- package/dist/plugins/functions/untracked-read.js +3 -2
- package/dist/plugins/functions/untracked-read.js.map +2 -2
- package/dist/plugins/functions/websocket.d.ts +3 -3
- package/dist/plugins/functions/websocket.js +18 -25
- package/dist/plugins/functions/websocket.js.map +2 -2
- package/dist/plugins/index.d.ts +34 -36
- package/dist/plugins/index.js +31 -35
- package/dist/plugins/index.js.map +2 -2
- package/dist/plugins/server-events/apply-elements.d.ts +1 -1
- package/dist/plugins/server-events/apply-elements.js +41 -40
- package/dist/plugins/server-events/apply-elements.js.map +2 -2
- package/dist/plugins/server-events/apply-state.js +9 -12
- package/dist/plugins/server-events/apply-state.js.map +2 -2
- package/dist/plugins/server-events/morph.d.ts +0 -2
- package/dist/plugins/server-events/morph.js +58 -55
- package/dist/plugins/server-events/morph.js.map +3 -3
- package/dist/presets/all.d.ts +0 -1
- package/dist/presets/all.js +22 -26
- package/dist/presets/all.js.map +2 -2
- package/dist/presets/essentials.d.ts +0 -1
- package/dist/presets/essentials.js +27 -9
- package/dist/presets/essentials.js.map +2 -2
- package/dist/presets/minimal.d.ts +0 -1
- package/dist/presets/minimal.js +2 -2
- package/dist/presets/minimal.js.map +2 -2
- package/dist/server.d.ts +108 -0
- package/dist/server.js +218 -0
- package/dist/server.js.map +7 -0
- package/dist/sigmx.standalone.js +1 -1
- package/dist/standalone.js.map +2 -2
- package/dist/vite.d.ts +2 -2
- package/dist/vite.js +48 -15
- package/dist/vite.js.map +2 -2
- package/package.json +21 -2
- package/dist/auto.d.ts +0 -1
- package/dist/auto.js +0 -7
- package/dist/auto.js.map +0 -7
- package/dist/core/csp.d.ts +0 -7
- package/dist/core/csp.js +0 -20
- package/dist/core/csp.js.map +0 -7
- package/dist/core/engine.d.ts +0 -10
- package/dist/core/engine.js +0 -200
- package/dist/core/engine.js.map +0 -7
- package/dist/core/expr.d.ts +0 -12
- package/dist/core/expr.js +0 -94
- package/dist/core/expr.js.map +0 -7
- package/dist/core/index.d.ts +0 -16
- package/dist/core/index.js +0 -46
- package/dist/core/index.js.map +0 -7
- package/dist/core/signals.d.ts +0 -42
- package/dist/core/signals.js +0 -195
- package/dist/core/signals.js.map +0 -7
- package/dist/core/store.d.ts +0 -32
- package/dist/core/store.js +0 -185
- package/dist/core/store.js.map +0 -7
- package/dist/core/types.d.ts +0 -101
- package/dist/core/types.js +0 -1
- package/dist/core/types.js.map +0 -7
- package/dist/plugins/actions/clipboard.d.ts +0 -2
- package/dist/plugins/actions/clipboard.js +0 -11
- package/dist/plugins/actions/clipboard.js.map +0 -7
- package/dist/plugins/actions/fit.d.ts +0 -2
- package/dist/plugins/actions/fit.js +0 -14
- package/dist/plugins/actions/fit.js.map +0 -7
- package/dist/plugins/actions/intl.d.ts +0 -2
- package/dist/plugins/actions/intl.js +0 -21
- package/dist/plugins/actions/intl.js.map +0 -7
- package/dist/plugins/actions/peek.d.ts +0 -2
- package/dist/plugins/actions/peek.js +0 -6
- package/dist/plugins/actions/peek.js.map +0 -7
- package/dist/plugins/actions/setAll.d.ts +0 -2
- package/dist/plugins/actions/setAll.js +0 -11
- package/dist/plugins/actions/setAll.js.map +0 -7
- package/dist/plugins/actions/toggleAll.d.ts +0 -2
- package/dist/plugins/actions/toggleAll.js +0 -11
- package/dist/plugins/actions/toggleAll.js.map +0 -7
- package/dist/plugins/attributes/attr.d.ts +0 -2
- package/dist/plugins/attributes/attr.js +0 -20
- package/dist/plugins/attributes/attr.js.map +0 -7
- package/dist/plugins/attributes/bind.d.ts +0 -6
- package/dist/plugins/attributes/bind.js +0 -81
- package/dist/plugins/attributes/bind.js.map +0 -7
- package/dist/plugins/attributes/class.d.ts +0 -2
- package/dist/plugins/attributes/class.js +0 -22
- package/dist/plugins/attributes/class.js.map +0 -7
- package/dist/plugins/attributes/computed.d.ts +0 -2
- package/dist/plugins/attributes/computed.js +0 -20
- package/dist/plugins/attributes/computed.js.map +0 -7
- package/dist/plugins/attributes/customValidity.d.ts +0 -2
- package/dist/plugins/attributes/customValidity.js +0 -14
- package/dist/plugins/attributes/customValidity.js.map +0 -7
- package/dist/plugins/attributes/effect.d.ts +0 -2
- package/dist/plugins/attributes/effect.js +0 -12
- package/dist/plugins/attributes/effect.js.map +0 -7
- package/dist/plugins/attributes/indicator.d.ts +0 -2
- package/dist/plugins/attributes/indicator.js +0 -20
- package/dist/plugins/attributes/indicator.js.map +0 -7
- package/dist/plugins/attributes/init.d.ts +0 -2
- package/dist/plugins/attributes/init.js +0 -14
- package/dist/plugins/attributes/init.js.map +0 -7
- package/dist/plugins/attributes/jsonSignals.d.ts +0 -2
- package/dist/plugins/attributes/jsonSignals.js +0 -15
- package/dist/plugins/attributes/jsonSignals.js.map +0 -7
- package/dist/plugins/attributes/matchMedia.d.ts +0 -2
- package/dist/plugins/attributes/matchMedia.js +0 -19
- package/dist/plugins/attributes/matchMedia.js.map +0 -7
- package/dist/plugins/attributes/on.d.ts +0 -5
- package/dist/plugins/attributes/on.js +0 -28
- package/dist/plugins/attributes/on.js.map +0 -7
- package/dist/plugins/attributes/onIntersect.d.ts +0 -2
- package/dist/plugins/attributes/onIntersect.js +0 -28
- package/dist/plugins/attributes/onIntersect.js.map +0 -7
- package/dist/plugins/attributes/onInterval.d.ts +0 -2
- package/dist/plugins/attributes/onInterval.js +0 -18
- package/dist/plugins/attributes/onInterval.js.map +0 -7
- package/dist/plugins/attributes/onRaf.d.ts +0 -1
- package/dist/plugins/attributes/onRaf.js +0 -19
- package/dist/plugins/attributes/onRaf.js.map +0 -7
- package/dist/plugins/attributes/onResize.d.ts +0 -1
- package/dist/plugins/attributes/onResize.js +0 -17
- package/dist/plugins/attributes/onResize.js.map +0 -7
- package/dist/plugins/attributes/onSignalPatch.d.ts +0 -5
- package/dist/plugins/attributes/onSignalPatch.js +0 -35
- package/dist/plugins/attributes/onSignalPatch.js.map +0 -7
- package/dist/plugins/attributes/persist.d.ts +0 -6
- package/dist/plugins/attributes/persist.js +0 -16
- package/dist/plugins/attributes/persist.js.map +0 -7
- package/dist/plugins/attributes/queryString.d.ts +0 -5
- package/dist/plugins/attributes/queryString.js +0 -54
- package/dist/plugins/attributes/queryString.js.map +0 -7
- package/dist/plugins/attributes/ref.d.ts +0 -2
- package/dist/plugins/attributes/ref.js +0 -13
- package/dist/plugins/attributes/ref.js.map +0 -7
- package/dist/plugins/attributes/replaceUrl.d.ts +0 -1
- package/dist/plugins/attributes/replaceUrl.js +0 -11
- package/dist/plugins/attributes/replaceUrl.js.map +0 -7
- package/dist/plugins/attributes/scrollIntoView.d.ts +0 -2
- package/dist/plugins/attributes/scrollIntoView.js +0 -19
- package/dist/plugins/attributes/scrollIntoView.js.map +0 -7
- package/dist/plugins/attributes/show.d.ts +0 -2
- package/dist/plugins/attributes/show.js +0 -19
- package/dist/plugins/attributes/show.js.map +0 -7
- package/dist/plugins/attributes/signals.d.ts +0 -2
- package/dist/plugins/attributes/signals.js +0 -13
- package/dist/plugins/attributes/signals.js.map +0 -7
- package/dist/plugins/attributes/style.d.ts +0 -2
- package/dist/plugins/attributes/style.js +0 -25
- package/dist/plugins/attributes/style.js.map +0 -7
- package/dist/plugins/attributes/text.d.ts +0 -1
- package/dist/plugins/attributes/text.js +0 -13
- package/dist/plugins/attributes/text.js.map +0 -7
- package/dist/plugins/attributes/viewTransition.d.ts +0 -1
- package/dist/plugins/attributes/viewTransition.js +0 -11
- package/dist/plugins/attributes/viewTransition.js.map +0 -7
- package/dist/plugins/directives/transition-name.d.ts +0 -1
- package/dist/plugins/directives/transition-name.js +0 -11
- package/dist/plugins/directives/transition-name.js.map +0 -7
- package/dist/plugins/directives/trap.d.ts +0 -5
- package/dist/plugins/directives/trap.js +0 -48
- package/dist/plugins/directives/trap.js.map +0 -7
- package/dist/sigmx.auto.js +0 -5
- package/dist/utils/object.d.ts +0 -9
- package/dist/utils/object.js +0 -26
- package/dist/utils/object.js.map +0 -7
- package/dist/utils/text.d.ts +0 -7
- package/dist/utils/text.js +0 -15
- package/dist/utils/text.js.map +0 -7
- package/dist/utils/timing.d.ts +0 -14
- package/dist/utils/timing.js +0 -58
- package/dist/utils/timing.js.map +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/kernel/runtime.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,SAAS,wBAAwB;
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["import { type CaseStyle, recase } from '../lib/casing.js';\nimport { functionCompiler } from './compile.js';\nimport type {\n ActionCtx,\n AttributePlugin,\n Ctx,\n El,\n Evaluator,\n Mods,\n Plugin,\n Runtime,\n RuntimeOptions,\n Sigmx,\n} from './contracts.js';\nimport { rootEffect } from './reactive.js';\nimport { createStore } from './state.js';\n\nconst isEl = (n: Node): n is El => n.nodeType === 1;\n/** An element (or shadow root) followed by every element under it; nothing for text and comment nodes. */\nconst tree = (n: Node): El[] =>\n (n as ParentNode).querySelectorAll ? [...(isEl(n) ? [n] : []), ...(n as ParentNode).querySelectorAll<El>('*')] : [];\n\ntype Parsed = { plugin: string; key: string | undefined; mods: Mods };\n\n/** 'on:click__debounce.300ms__prevent' \u2192 { plugin: 'on', key: 'click', mods: {debounce: ['300ms'], prevent: []} } */\nexport const parseAttr = (raw: string): Parsed => {\n const [head, ...modParts] = raw.split('__');\n const [, plugin, key] = /^([^:]*)(?::(.*))?$/.exec(head) as string[];\n return {\n plugin,\n key,\n mods: new Map(\n modParts.map((m) => {\n const [name, ...args] = m.split('.');\n return [name, args];\n }),\n ),\n };\n};\n\n/** The rest of `s` after the first prefix in `list` that it starts with; undefined when none matches. */\nconst cut = (list: readonly string[], s: string): string | undefined => {\n for (const p of list) if (s.startsWith(p)) return s.slice(p.length);\n};\n\n/** Low-level constructor: you supply the expression pipeline. `createSigmx` wraps it with the runtime compiler. */\nexport const createRuntime = (options: RuntimeOptions): Sigmx => {\n const prefixes = ([] as string[]).concat(options.prefix ?? 'data-');\n const eventPrefixes = ([] as string[]).concat(options.eventPrefix ?? 'sigmx-');\n const store = options.store ?? createStore();\n const { expressions } = options;\n const onError = options.onError ?? ((e, info) => console.error(e, info));\n const attributes: Record<string, AttributePlugin> = Object.create(null);\n\n const runtime: Runtime = {\n prefixes,\n attr: (name) => prefixes[0] + name,\n store,\n compiler: options.compile ?? functionCompiler,\n emit: (type, detail) => document.dispatchEvent(new CustomEvent(`sigmx-${type}`, { detail })),\n call: (name, ctx, args) => {\n const a = runtime.actions[name];\n if (!a) throw ctx.error(`unknown action @${name}`);\n return a.call(ctx, ...args);\n },\n eventPrefixes,\n handle: (event, data) => {\n const h = runtime.handlers[cut(eventPrefixes, event) ?? event];\n h?.handle(runtime, data);\n return !!h;\n },\n attributes,\n actions: Object.create(null),\n handlers: Object.create(null),\n };\n\n // element \u2192 attribute name \u2192 dispose\n const mounted = new Map<El, Map<string, () => void>>();\n const roots = new Set<El | ShadowRoot>();\n const ignoreAny = prefixes.map((p) => `[${p}ignore]`).join();\n const ignored = (el: El) => !!el.closest(ignoreAny);\n let destroyed = false;\n\n const unmount = (els: Iterable<El>): void => {\n for (const el of els) {\n const m = mounted.get(el);\n if (m && mounted.delete(el)) for (const d of m.values()) d();\n }\n };\n\n const unmountAttr = (el: El, attr: string): void => {\n const m = mounted.get(el);\n m?.get(attr)?.();\n m?.delete(attr);\n };\n\n const mount = (el: El, attr: string, raw: string, value: string, only?: Set<string>): void => {\n const { plugin: name, key, mods } = parseAttr(raw);\n const plugin = attributes[name];\n if (!plugin || (only && !only.has(name))) return;\n unmountAttr(el, attr);\n\n const disposers: (() => void)[] = [];\n const cleanup = (f: () => void) => {\n disposers.push(f);\n return () => {\n const i = disposers.indexOf(f);\n if (i >= 0) disposers.splice(i, 1);\n };\n };\n const info = { plugin: name, el, attr };\n const error: Ctx['error'] = (message, extra) =>\n Object.assign(new Error(`${prefixes[0]}${name}: ${message}`), { info: { ...info, ...extra } });\n const report = (e: unknown) => onError(e, info);\n let fn: Evaluator | undefined;\n const watched = new WeakSet<Promise<unknown>>(); // promises already routed to onError\n const watch = (r: unknown) => {\n if (r instanceof Promise && !watched.has(r)) {\n watched.add(r);\n r.catch(report);\n }\n };\n const ctx: Ctx = {\n el,\n plugin: name,\n attr,\n key,\n value,\n mods,\n cased: (style = 'camel') => recase(key ?? '', (mods.get('case')?.[0] as CaseStyle) || style),\n evaluate: (evt, ...args) => {\n if (plugin.literal && !mods.has('dynamic')) return value;\n fn ??= expressions(value, ['el', 'evt', ...(plugin.args ?? [])]);\n const actx: ActionCtx = { el, evt, store, runtime, error, cleanup, report };\n const actions = new Proxy(\n {},\n {\n get:\n (_, name: string) =>\n (...args: any[]) => {\n const r = runtime.call(name, actx, args);\n watch(r); // async actions (requests) reject long after the expression returned\n return r;\n },\n },\n );\n const r = fn(store, actions, el, evt, ...args);\n watch(r); // an expression's own rejected promise is reported too, once\n return r;\n },\n // Root-owned: an attribute mounted from inside another effect must outlive that effect's re-runs.\n effect: (f) => {\n cleanup(rootEffect(f, report));\n },\n listen: (target, type, f, opts) => {\n const h = (e: Event) => {\n try {\n f(e);\n } catch (err) {\n report(err);\n }\n };\n target.addEventListener(type, h, opts);\n cleanup(() => target.removeEventListener(type, h, opts));\n },\n cleanup,\n error,\n report,\n store,\n runtime,\n };\n\n let m = mounted.get(el);\n if (!m) {\n m = new Map();\n mounted.set(el, m);\n }\n m.set(attr, () => {\n for (const d of disposers.splice(0)) d();\n });\n\n try {\n // Contract checks: a keyed directive without a key would otherwise write to the path ''.\n for (const [k, v] of [\n ['key', key],\n ['value', value],\n ] as const) {\n const rule = plugin[k];\n if (rule && (rule === 'required') === !v) throw error(`${rule === 'required' ? 'needs a' : 'takes no'} ${k}`);\n }\n const r: unknown = plugin.mount(ctx);\n if (typeof r === 'function') cleanup(r as () => void);\n else watch(r); // an async mount that rejects is reported, not lost\n } catch (e) {\n report(e);\n }\n };\n\n const mountEls = (els: Iterable<El>, only?: Set<string>): void => {\n for (const el of els) {\n if (ignored(el)) continue;\n for (const { name, value } of [...el.attributes]) {\n const raw = cut(prefixes, name);\n // Observers can report a subtree more than once (nested insertions); a mounted attribute stays as it is.\n if (raw && !mounted.get(el)?.has(name)) mount(el, name, raw, value, only);\n }\n }\n };\n\n const observer = new MutationObserver((records) => {\n for (const { type, target, attributeName, addedNodes, removedNodes } of records) {\n if (type === 'childList') {\n // A node that is still connected was moved (teleport, morph), not removed: it keeps its state.\n for (const n of removedNodes) if (!n.isConnected) unmount(tree(n));\n for (const n of addedNodes) mountEls(tree(n));\n } else if (attributeName && isEl(target) && !ignored(target)) {\n const raw = cut(prefixes, attributeName);\n if (!raw) continue;\n const value = target.getAttribute(attributeName);\n if (value === null) unmountAttr(target, attributeName);\n else mount(target, attributeName, raw, value);\n }\n }\n });\n\n const apply = (root: El | ShadowRoot = document.documentElement, observe = true, only?: Set<string>) => {\n if (destroyed) return;\n mountEls(tree(root), only);\n if (observe && !roots.has(root)) {\n observer.observe(root, { subtree: true, childList: true, attributes: true });\n roots.add(root);\n }\n };\n\n const use = (...plugins: Plugin[]): void => {\n const added = new Set<string>();\n for (const p of plugins) {\n (runtime as any)[`${p.type}s`][p.name] = p;\n if (p.type === 'attribute') added.add(p.name);\n }\n if (added.size) for (const r of roots) apply(r, false, added);\n };\n\n const stopPatches = store.onPatch((patch) => runtime.emit('signal-patch', patch));\n use(...(options.plugins ?? []));\n\n const sigmx: Sigmx = {\n runtime,\n store,\n get $() {\n return store.$;\n },\n apply: (root, observe) => apply(root, observe),\n use,\n destroy: () => {\n destroyed = true;\n observer.disconnect();\n stopPatches();\n unmount([...mounted.keys()]);\n roots.clear();\n },\n };\n\n if (options.autoStart ?? true) {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => sigmx.apply(), { once: true });\n } else {\n sigmx.apply();\n }\n }\n return sigmx;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["name", "args", "r"]
|
|
7
7
|
}
|
package/dist/kernel/scan.d.ts
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import type { Plugin } from './contracts.js';
|
|
2
2
|
export type PluginMeta = {
|
|
3
|
-
/** Export name, e.g. `httpGet`; what the generated module imports. */
|
|
4
3
|
export: string;
|
|
5
|
-
/** Registered name, e.g. `get`; what markup refers to. */
|
|
6
4
|
name: string;
|
|
7
5
|
type: Plugin['type'];
|
|
8
|
-
/** Module to import from; built-ins come from `sigmx/plugins`. */
|
|
9
6
|
from: string;
|
|
10
|
-
|
|
7
|
+
literal?: boolean;
|
|
11
8
|
args?: string[];
|
|
12
9
|
};
|
|
13
|
-
/** Plugins that only make sense together. */
|
|
14
10
|
export declare const implied: Record<string, string[]>;
|
|
15
|
-
/** Metadata for every built-in plugin. */
|
|
16
11
|
export declare const builtinPlugins: () => PluginMeta[];
|
|
17
12
|
/**
|
|
18
13
|
* Read a custom plugin's metadata from its source without executing it: finds
|
|
@@ -22,21 +17,17 @@ export declare const customPluginMeta: (exportName: string, source: string, from
|
|
|
22
17
|
/** True if `source` refers to the plugin: `data-<name>` for directives, `@name(` for functions, the name as a string for handlers. */
|
|
23
18
|
export declare const mentions: (source: string, p: PluginMeta, prefixes: string[]) => boolean;
|
|
24
19
|
export type Selection = {
|
|
25
|
-
/** Selected plugins in a stable order. */
|
|
26
20
|
plugins: PluginMeta[];
|
|
27
|
-
/** Why each one is in: 'used', 'always', or the plugin that implied it. */
|
|
28
21
|
reasons: Record<string, string>;
|
|
29
|
-
/** Known plugins that were left out. */
|
|
30
22
|
unused: string[];
|
|
31
23
|
};
|
|
32
24
|
/**
|
|
33
25
|
* Decide which plugins to ship. `sources` are file contents; `custom` are extra plugins (from
|
|
34
26
|
* `customPluginMeta`); `always` are export names that ship regardless.
|
|
35
27
|
*/
|
|
36
|
-
export declare const selectPlugins: (sources: string[], { prefixes, always, custom }?: {
|
|
28
|
+
export declare const selectPlugins: (sources: string[], { prefixes, always, custom, }?: {
|
|
37
29
|
prefixes?: string[];
|
|
38
30
|
always?: string[];
|
|
39
31
|
custom?: PluginMeta[];
|
|
40
32
|
}) => Selection;
|
|
41
|
-
/** JavaScript source for a module exporting `plugins` (and the selection report). */
|
|
42
33
|
export declare const generatePluginsModule: (sel: Selection) => string;
|
package/dist/kernel/scan.js
CHANGED
|
@@ -6,34 +6,49 @@ const implied = {
|
|
|
6
6
|
};
|
|
7
7
|
const builtinPlugins = () => Object.entries(builtins).filter(([, v]) => v && typeof v === "object" && "type" in v).map(([key, v]) => {
|
|
8
8
|
const p = v;
|
|
9
|
-
return {
|
|
9
|
+
return {
|
|
10
|
+
export: key,
|
|
11
|
+
name: p.name,
|
|
12
|
+
type: p.type,
|
|
13
|
+
from: "sigmx/plugins",
|
|
14
|
+
literal: p.literal,
|
|
15
|
+
args: p.args
|
|
16
|
+
};
|
|
10
17
|
});
|
|
11
18
|
const customPluginMeta = (exportName, source, from) => {
|
|
12
|
-
const re = new RegExp(
|
|
19
|
+
const re = new RegExp(
|
|
20
|
+
`export\\s+const\\s+${exportName}\\s*(?::[^=]+)?=\\s*(attribute|action|handler)\\s*\\(\\s*\\{([\\s\\S]*?)\\}\\s*\\)`,
|
|
21
|
+
"m"
|
|
22
|
+
);
|
|
13
23
|
const m = re.exec(source);
|
|
14
24
|
if (!m) return;
|
|
15
25
|
const body = m[2];
|
|
16
26
|
const name = /\bname\s*:\s*['"`]([^'"`]+)['"`]/.exec(body)?.[1];
|
|
17
27
|
if (!name) return;
|
|
18
|
-
const
|
|
28
|
+
const literal = /\bliteral\s*:\s*true/.test(body);
|
|
19
29
|
const args = /\bargs\s*:\s*\[([^\]]*)\]/.exec(body)?.[1];
|
|
20
30
|
return {
|
|
21
31
|
export: exportName,
|
|
22
32
|
name,
|
|
23
33
|
type: m[1],
|
|
24
34
|
from,
|
|
25
|
-
|
|
35
|
+
literal: literal || void 0,
|
|
26
36
|
args: args?.split(",").map((s) => s.trim().replace(/^['"`]|['"`]$/g, "")).filter(Boolean)
|
|
27
37
|
};
|
|
28
38
|
};
|
|
29
|
-
const
|
|
39
|
+
const esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
30
40
|
const mentions = (source, p, prefixes) => {
|
|
31
|
-
const n =
|
|
32
|
-
if (p.type === "attribute")
|
|
41
|
+
const n = esc(p.name);
|
|
42
|
+
if (p.type === "attribute")
|
|
43
|
+
return prefixes.some((pre) => new RegExp(`(^|[\\s"'\`<])${esc(pre)}${n}(?=[\\s=:_>"'\`/]|$)`, "m").test(source));
|
|
33
44
|
if (p.type === "action") return new RegExp(`@${n}\\s*\\(`).test(source);
|
|
34
45
|
return new RegExp(`['"\`](?:[\\w-]+-)?${n}['"\`]`).test(source);
|
|
35
46
|
};
|
|
36
|
-
const selectPlugins = (sources, {
|
|
47
|
+
const selectPlugins = (sources, {
|
|
48
|
+
prefixes = ["data-"],
|
|
49
|
+
always = [],
|
|
50
|
+
custom = []
|
|
51
|
+
} = {}) => {
|
|
37
52
|
const known = [...builtinPlugins(), ...custom];
|
|
38
53
|
const byExport = new Map(known.map((p) => [p.export, p]));
|
|
39
54
|
const reasons = {};
|
|
@@ -44,7 +59,9 @@ const selectPlugins = (sources, { prefixes = ["data-"], always = [], custom = []
|
|
|
44
59
|
};
|
|
45
60
|
for (const exp of always) add(exp, "always");
|
|
46
61
|
const text = sources.join("\n");
|
|
47
|
-
for (const p of known)
|
|
62
|
+
for (const p of known)
|
|
63
|
+
if (!reasons[p.export] && (p.type !== "handler" || custom.includes(p)) && mentions(text, p, prefixes))
|
|
64
|
+
add(p.export, "used");
|
|
48
65
|
const plugins = known.filter((p) => reasons[p.export]);
|
|
49
66
|
return { plugins, reasons, unused: known.filter((p) => !reasons[p.export]).map((p) => p.export) };
|
|
50
67
|
};
|
package/dist/kernel/scan.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/kernel/scan.ts"],
|
|
4
|
-
"sourcesContent": ["//
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["// Node only; never bundled for the browser.\nimport * as builtins from '../plugins/index.js';\nimport type { Plugin } from './contracts.js';\n\nexport type PluginMeta = {\n export: string;\n name: string;\n type: Plugin['type'];\n from: string;\n literal?: boolean;\n args?: string[];\n};\n\nconst NETWORK = ['httpGet', 'httpPost', 'httpPut', 'httpPatch', 'httpDelete', 'websocket', 'boost'];\n\nexport const implied: Record<string, string[]> = {\n ...Object.fromEntries(NETWORK.map((n) => [n, ['applyElements', 'applyState']])),\n boost: ['httpGet', 'httpPost', 'applyElements', 'applyState'],\n};\n\nexport const builtinPlugins = (): PluginMeta[] =>\n Object.entries(builtins)\n .filter(([, v]) => v && typeof v === 'object' && 'type' in (v as object))\n .map(([key, v]) => {\n const p = v as Plugin;\n return {\n export: key,\n name: p.name,\n type: p.type,\n from: 'sigmx/plugins',\n literal: (p as any).literal,\n args: (p as any).args,\n };\n });\n\n/**\n * Read a custom plugin's metadata from its source without executing it: finds\n * `attribute({ name: 'x', ... })`, `action({...})` or `handler({...})` near `export const <exportName>`.\n */\nexport const customPluginMeta = (exportName: string, source: string, from: string): PluginMeta | undefined => {\n const re = new RegExp(\n `export\\\\s+const\\\\s+${exportName}\\\\s*(?::[^=]+)?=\\\\s*(attribute|action|handler)\\\\s*\\\\(\\\\s*\\\\{([\\\\s\\\\S]*?)\\\\}\\\\s*\\\\)`,\n 'm',\n );\n const m = re.exec(source);\n if (!m) return;\n const body = m[2];\n const name = /\\bname\\s*:\\s*['\"`]([^'\"`]+)['\"`]/.exec(body)?.[1];\n if (!name) return;\n const literal = /\\bliteral\\s*:\\s*true/.test(body);\n const args = /\\bargs\\s*:\\s*\\[([^\\]]*)\\]/.exec(body)?.[1];\n return {\n export: exportName,\n name,\n type: m[1] as Plugin['type'],\n from,\n literal: literal || undefined,\n args: args\n ?.split(',')\n .map((s) => s.trim().replace(/^['\"`]|['\"`]$/g, ''))\n .filter(Boolean),\n };\n};\n\nconst esc = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/** True if `source` refers to the plugin: `data-<name>` for directives, `@name(` for functions, the name as a string for handlers. */\nexport const mentions = (source: string, p: PluginMeta, prefixes: string[]): boolean => {\n const n = esc(p.name);\n if (p.type === 'attribute')\n return prefixes.some((pre) => new RegExp(`(^|[\\\\s\"'\\`<])${esc(pre)}${n}(?=[\\\\s=:_>\"'\\`/]|$)`, 'm').test(source));\n if (p.type === 'action') return new RegExp(`@${n}\\\\s*\\\\(`).test(source);\n return new RegExp(`['\"\\`](?:[\\\\w-]+-)?${n}['\"\\`]`).test(source);\n};\n\nexport type Selection = {\n plugins: PluginMeta[];\n reasons: Record<string, string>;\n unused: string[];\n};\n\n/**\n * Decide which plugins to ship. `sources` are file contents; `custom` are extra plugins (from\n * `customPluginMeta`); `always` are export names that ship regardless.\n */\nexport const selectPlugins = (\n sources: string[],\n {\n prefixes = ['data-'],\n always = [],\n custom = [],\n }: { prefixes?: string[]; always?: string[]; custom?: PluginMeta[] } = {},\n): Selection => {\n const known = [...builtinPlugins(), ...custom];\n const byExport = new Map(known.map((p) => [p.export, p]));\n const reasons: Record<string, string> = {};\n const add = (exp: string, why: string) => {\n if (!byExport.has(exp) || reasons[exp]) return;\n reasons[exp] = why;\n for (const dep of implied[exp] ?? []) add(dep, exp);\n };\n for (const exp of always) add(exp, 'always');\n const text = sources.join('\\n');\n for (const p of known)\n if (!reasons[p.export] && (p.type !== 'handler' || custom.includes(p)) && mentions(text, p, prefixes))\n add(p.export, 'used');\n const plugins = known.filter((p) => reasons[p.export]);\n return { plugins, reasons, unused: known.filter((p) => !reasons[p.export]).map((p) => p.export) };\n};\n\nexport const generatePluginsModule = (sel: Selection): string => {\n const groups = new Map<string, string[]>();\n for (const p of sel.plugins) groups.set(p.from, [...(groups.get(p.from) ?? []), p.export]);\n const imports = [...groups]\n .map(([from, names]) => `import { ${names.join(', ')} } from ${JSON.stringify(from)}`)\n .join('\\n');\n return `${imports}\\nexport const plugins = [${sel.plugins.map((p) => p.export).join(', ')}]\\nexport const report = ${JSON.stringify({ reasons: sel.reasons, unused: sel.unused }, null, 2)}\\n`;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/kernel/state.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Signal } from './reactive.js';
|
|
2
1
|
import { type Filter } from '../lib/objects.js';
|
|
2
|
+
import { Signal } from './reactive.js';
|
|
3
3
|
export type Patch = Record<string, any>;
|
|
4
4
|
export interface Store {
|
|
5
5
|
/** Value at a dotted path: a leaf value, a namespace proxy, or undefined. Reads subscribe. */
|
|
@@ -13,20 +13,17 @@ export interface Store {
|
|
|
13
13
|
}): void;
|
|
14
14
|
remove(path: string): void;
|
|
15
15
|
has(path: string): boolean;
|
|
16
|
-
/** Install a computed (or any signal) as the leaf at a path. */
|
|
17
16
|
define(path: string, node: Signal<any>): void;
|
|
18
|
-
/** Leaf paths,
|
|
19
|
-
paths(filter?: Filter
|
|
20
|
-
|
|
17
|
+
/** Leaf paths, filtered; `computed: false` leaves out computed signals. */
|
|
18
|
+
paths(filter?: Filter, options?: {
|
|
19
|
+
computed?: boolean;
|
|
20
|
+
}): string[];
|
|
21
21
|
snapshot(filter?: Filter, options?: {
|
|
22
22
|
at?: string;
|
|
23
23
|
computed?: boolean;
|
|
24
24
|
}): Patch;
|
|
25
25
|
/** Called after each settled batch with the nested object of changed paths (null = removed). */
|
|
26
26
|
onPatch(fn: (patch: Patch) => void): () => void;
|
|
27
|
-
/** Root namespace proxy: `$.count`, `$.user.name = 'x'`, `JSON.stringify($)`. */
|
|
28
27
|
readonly $: any;
|
|
29
|
-
/** Identifier scope for compiled expressions: resolves `$count`, `$user`, and `$`. */
|
|
30
|
-
readonly scope: object;
|
|
31
28
|
}
|
|
32
29
|
export declare const createStore: () => Store;
|
package/dist/kernel/state.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
const
|
|
4
|
-
const
|
|
1
|
+
import { expand, isPlain, safeKey, toPredicate } from "../lib/objects.js";
|
|
2
|
+
import { batch, Computed, onSettled, Signal } from "./reactive.js";
|
|
3
|
+
const split = (p) => {
|
|
4
|
+
const i = p.lastIndexOf(".");
|
|
5
|
+
return [i < 0 ? "" : p.slice(0, i), p.slice(i + 1)];
|
|
6
|
+
};
|
|
5
7
|
const join = (a, b) => a ? `${a}.${b}` : b;
|
|
6
|
-
const under = (p, at) => !at || p
|
|
8
|
+
const under = (p, at) => !at || p.startsWith(`${at}.`);
|
|
7
9
|
const str = (k) => typeof k === "string";
|
|
10
|
+
const rawOf = /* @__PURE__ */ new WeakMap();
|
|
8
11
|
const createStore = () => {
|
|
9
12
|
const leaves = /* @__PURE__ */ new Map();
|
|
10
13
|
const kids = /* @__PURE__ */ new Map([["", /* @__PURE__ */ new Set()]]);
|
|
@@ -12,14 +15,24 @@ const createStore = () => {
|
|
|
12
15
|
const pending = /* @__PURE__ */ new Map();
|
|
13
16
|
const listeners = /* @__PURE__ */ new Set();
|
|
14
17
|
const nsCache = /* @__PURE__ */ new Map();
|
|
15
|
-
const
|
|
18
|
+
const proxies = /* @__PURE__ */ new WeakMap();
|
|
19
|
+
const link = (p) => {
|
|
20
|
+
const [parent, name] = split(p);
|
|
21
|
+
ensureNs(parent).add(name);
|
|
22
|
+
shape.bump();
|
|
23
|
+
};
|
|
24
|
+
const unlink = (p) => {
|
|
25
|
+
const [parent, name] = split(p);
|
|
26
|
+
kids.get(parent)?.delete(name);
|
|
27
|
+
shape.bump();
|
|
28
|
+
};
|
|
16
29
|
const ensureNs = (p) => {
|
|
17
30
|
let set2 = kids.get(p);
|
|
18
31
|
if (!set2) {
|
|
19
32
|
if (leaves.has(p)) dropLeaf(p);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
set2 = /* @__PURE__ */ new Set();
|
|
34
|
+
kids.set(p, set2);
|
|
35
|
+
link(p);
|
|
23
36
|
}
|
|
24
37
|
return set2;
|
|
25
38
|
};
|
|
@@ -27,10 +40,10 @@ const createStore = () => {
|
|
|
27
40
|
const s = leaves.get(p);
|
|
28
41
|
if (!s) return;
|
|
29
42
|
leaves.delete(p);
|
|
30
|
-
|
|
43
|
+
unlink(p);
|
|
31
44
|
pending.set(p, null);
|
|
32
45
|
s.bump();
|
|
33
|
-
|
|
46
|
+
if (s instanceof Computed) s.dispose();
|
|
34
47
|
};
|
|
35
48
|
const dropNs = (p) => {
|
|
36
49
|
const set2 = kids.get(p);
|
|
@@ -38,34 +51,35 @@ const createStore = () => {
|
|
|
38
51
|
for (const k of [...set2]) remove(join(p, k));
|
|
39
52
|
if (p) {
|
|
40
53
|
kids.delete(p);
|
|
41
|
-
kids.get(parentOf(p))?.delete(nameOf(p));
|
|
42
54
|
nsCache.delete(p);
|
|
55
|
+
unlink(p);
|
|
43
56
|
}
|
|
44
|
-
shape.bump();
|
|
45
57
|
};
|
|
46
58
|
const remove = (p) => batch(() => {
|
|
47
59
|
dropLeaf(p);
|
|
48
60
|
dropNs(p);
|
|
49
61
|
});
|
|
50
62
|
const define = (p, node) => batch(() => {
|
|
51
|
-
|
|
63
|
+
dropNs(p);
|
|
52
64
|
const old = leaves.get(p);
|
|
53
65
|
leaves.set(p, node);
|
|
54
|
-
|
|
55
|
-
old
|
|
56
|
-
|
|
66
|
+
link(p);
|
|
67
|
+
if (old) {
|
|
68
|
+
old.bump();
|
|
69
|
+
if (old instanceof Computed) old.dispose();
|
|
70
|
+
}
|
|
57
71
|
});
|
|
58
72
|
const set = (p, v) => batch(() => {
|
|
59
73
|
if (v == null) return remove(p);
|
|
74
|
+
v = (v && rawOf.get(v)) ?? v;
|
|
60
75
|
if (isPlain(v)) {
|
|
61
|
-
const
|
|
62
|
-
for (const k
|
|
63
|
-
for (const k in v) set(join(p, k), v[k]);
|
|
76
|
+
for (const k of [...ensureNs(p)]) if (!(k in v)) remove(join(p, k));
|
|
77
|
+
for (const k in v) if (safeKey(k)) set(join(p, k), v[k]);
|
|
64
78
|
return;
|
|
65
79
|
}
|
|
66
|
-
|
|
80
|
+
dropNs(p);
|
|
67
81
|
const s = leaves.get(p);
|
|
68
|
-
if (s instanceof Computed) throw new Error(`"${p}" is
|
|
82
|
+
if (s instanceof Computed) throw new Error(`computed "${p}" is read-only`);
|
|
69
83
|
if (s) {
|
|
70
84
|
if (Object.is(s.peek(), v)) return;
|
|
71
85
|
s.value = v;
|
|
@@ -76,33 +90,57 @@ const createStore = () => {
|
|
|
76
90
|
});
|
|
77
91
|
const merge = (patch, { at = "", ifMissing = false } = {}) => batch(() => {
|
|
78
92
|
if (!isPlain(patch)) return;
|
|
79
|
-
|
|
80
|
-
|
|
93
|
+
const keys = Object.keys(patch).filter(safeKey);
|
|
94
|
+
if (keys.length) ensureNs(at);
|
|
95
|
+
for (const k of keys) {
|
|
81
96
|
const p = join(at, k);
|
|
82
97
|
const v = patch[k];
|
|
98
|
+
const leaf = leaves.get(p);
|
|
99
|
+
if (leaf && (ifMissing || leaf instanceof Computed)) continue;
|
|
83
100
|
if (v === null) {
|
|
84
101
|
if (!ifMissing) remove(p);
|
|
85
|
-
} else if (isPlain(v)) {
|
|
86
|
-
|
|
87
|
-
} else if (!(ifMissing && (leaves.has(p) || kids.has(p))) && !(leaves.get(p) instanceof Computed)) {
|
|
88
|
-
set(p, v);
|
|
89
|
-
}
|
|
102
|
+
} else if (isPlain(v)) merge(v, { at: p, ifMissing });
|
|
103
|
+
else if (!(ifMissing && kids.has(p))) set(p, v);
|
|
90
104
|
}
|
|
91
105
|
});
|
|
106
|
+
const has = (p) => leaves.has(p) || kids.has(p);
|
|
92
107
|
const wrapArray = (raw, s, p) => {
|
|
93
|
-
let
|
|
94
|
-
if (!
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
s.bump();
|
|
98
|
-
};
|
|
99
|
-
px = new Proxy(raw, {
|
|
100
|
-
set: (t, k, v) => (t[k] = v, touch(), true),
|
|
101
|
-
deleteProperty: (t, k) => (delete t[k], touch(), true)
|
|
102
|
-
});
|
|
103
|
-
arrCache.set(raw, px);
|
|
108
|
+
let cache = proxies.get(s);
|
|
109
|
+
if (!cache) {
|
|
110
|
+
cache = /* @__PURE__ */ new WeakMap();
|
|
111
|
+
proxies.set(s, cache);
|
|
104
112
|
}
|
|
105
|
-
|
|
113
|
+
const touch = () => {
|
|
114
|
+
pending.set(p, raw);
|
|
115
|
+
s.bump();
|
|
116
|
+
return true;
|
|
117
|
+
};
|
|
118
|
+
const wrap = (target) => {
|
|
119
|
+
let px = cache?.get(target);
|
|
120
|
+
if (!px) {
|
|
121
|
+
px = new Proxy(target, {
|
|
122
|
+
get: (t, k, r) => {
|
|
123
|
+
const v = Reflect.get(t, k, r);
|
|
124
|
+
if (typeof v === "function" && Array.isArray(t)) return (...a) => batch(() => v.apply(r, a));
|
|
125
|
+
if (!v || typeof v !== "object" || !(Array.isArray(v) || isPlain(v))) return v;
|
|
126
|
+
const d = Object.getOwnPropertyDescriptor(t, k);
|
|
127
|
+
return d && !d.configurable && !d.writable ? v : wrap(v);
|
|
128
|
+
},
|
|
129
|
+
set: (t, k, v) => {
|
|
130
|
+
t[k] = (v && rawOf.get(v)) ?? v;
|
|
131
|
+
return touch();
|
|
132
|
+
},
|
|
133
|
+
deleteProperty: (t, k) => {
|
|
134
|
+
delete t[k];
|
|
135
|
+
return touch();
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
cache?.set(target, px);
|
|
139
|
+
rawOf.set(px, target);
|
|
140
|
+
}
|
|
141
|
+
return px;
|
|
142
|
+
};
|
|
143
|
+
return wrap(raw);
|
|
106
144
|
};
|
|
107
145
|
const get = (p) => {
|
|
108
146
|
const s = leaves.get(p);
|
|
@@ -110,51 +148,49 @@ const createStore = () => {
|
|
|
110
148
|
const v = s.value;
|
|
111
149
|
return Array.isArray(v) ? wrapArray(v, s, p) : v;
|
|
112
150
|
}
|
|
113
|
-
if (kids.has(p)) return ns(p);
|
|
114
151
|
shape.value;
|
|
115
|
-
return
|
|
152
|
+
if (kids.has(p)) return ns(p);
|
|
116
153
|
};
|
|
117
154
|
const ns = (p) => {
|
|
118
155
|
let px = nsCache.get(p);
|
|
119
156
|
if (!px) {
|
|
120
|
-
const names = () =>
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
157
|
+
const names = (k) => {
|
|
158
|
+
shape.value;
|
|
159
|
+
return str(k) && !!kids.get(p)?.has(k);
|
|
160
|
+
};
|
|
161
|
+
px = new Proxy(
|
|
162
|
+
{},
|
|
163
|
+
{
|
|
164
|
+
get: (_, k) => !str(k) ? void 0 : k === "toJSON" ? () => snapshot(void 0, { at: p }) : get(join(p, k)),
|
|
165
|
+
set: (_, k, v) => {
|
|
166
|
+
if (str(k)) set(join(p, k), v);
|
|
167
|
+
return true;
|
|
168
|
+
},
|
|
169
|
+
deleteProperty: (_, k) => {
|
|
170
|
+
if (str(k)) remove(join(p, k));
|
|
171
|
+
return true;
|
|
172
|
+
},
|
|
173
|
+
has: (_, k) => names(k),
|
|
174
|
+
ownKeys: () => {
|
|
175
|
+
shape.value;
|
|
176
|
+
return [...kids.get(p) ?? []];
|
|
177
|
+
},
|
|
178
|
+
getOwnPropertyDescriptor: (_, k) => names(k) ? { enumerable: true, configurable: true, writable: true, value: get(join(p, k)) } : void 0
|
|
179
|
+
}
|
|
180
|
+
);
|
|
129
181
|
nsCache.set(p, px);
|
|
130
182
|
}
|
|
131
183
|
return px;
|
|
132
184
|
};
|
|
133
|
-
const
|
|
134
|
-
has: (_, k) => str(k) && k[0] === "$",
|
|
135
|
-
get: (_, k) => !str(k) ? void 0 : k === "$" ? ns("") : get(k.slice(1)),
|
|
136
|
-
set: (_, k, v) => {
|
|
137
|
-
if (str(k)) k === "$" ? merge(v) : set(k.slice(1), v);
|
|
138
|
-
return true;
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
const paths = (filter) => {
|
|
185
|
+
const paths = (filter, { computed = true } = {}) => {
|
|
142
186
|
shape.value;
|
|
143
187
|
const ok = toPredicate(filter);
|
|
144
|
-
return [...leaves
|
|
188
|
+
return [...leaves].filter(([p, s]) => ok(p) && (computed || !(s instanceof Computed))).map(([p]) => p);
|
|
145
189
|
};
|
|
146
190
|
const snapshot = (filter, { at = "", computed = true } = {}) => {
|
|
147
|
-
shape.value;
|
|
148
|
-
const ok = toPredicate(filter);
|
|
149
191
|
const out = {};
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
if (!under(p, at) || !ok(p) || !computed && s instanceof Computed) continue;
|
|
153
|
-
expand(out, rel(p), s.value);
|
|
154
|
-
}
|
|
155
|
-
for (const p of kids.keys()) {
|
|
156
|
-
if (p && p !== at && under(p, at) && ok(p) && !kids.get(p).size) expand(out, rel(p), {});
|
|
157
|
-
}
|
|
192
|
+
for (const p of paths(filter, { computed }))
|
|
193
|
+
if (under(p, at)) expand(out, at ? p.slice(at.length + 1) : p, leaves.get(p)?.value);
|
|
158
194
|
return out;
|
|
159
195
|
};
|
|
160
196
|
onSettled(() => {
|
|
@@ -169,15 +205,17 @@ const createStore = () => {
|
|
|
169
205
|
set,
|
|
170
206
|
merge,
|
|
171
207
|
remove,
|
|
172
|
-
has
|
|
208
|
+
has,
|
|
173
209
|
define,
|
|
174
210
|
paths,
|
|
175
211
|
snapshot,
|
|
176
|
-
onPatch: (fn) =>
|
|
212
|
+
onPatch: (fn) => {
|
|
213
|
+
listeners.add(fn);
|
|
214
|
+
return () => listeners.delete(fn);
|
|
215
|
+
},
|
|
177
216
|
get $() {
|
|
178
217
|
return ns("");
|
|
179
|
-
}
|
|
180
|
-
scope
|
|
218
|
+
}
|
|
181
219
|
};
|
|
182
220
|
};
|
|
183
221
|
export {
|