@adaas/are-html 0.0.20 → 0.0.22
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/.conf/tsconfig.base.json +1 -0
- package/.conf/tsconfig.browser.json +1 -0
- package/.conf/tsconfig.node.json +1 -0
- package/dist/browser/index.d.mts +206 -7
- package/dist/browser/index.mjs +527 -65
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.d.mts +44 -1
- package/dist/node/directives/AreDirectiveFor.directive.d.ts +44 -1
- package/dist/node/directives/AreDirectiveFor.directive.js +102 -6
- package/dist/node/directives/AreDirectiveFor.directive.js.map +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.mjs +102 -6
- package/dist/node/directives/AreDirectiveFor.directive.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveShow.directive.d.mts +32 -0
- package/dist/node/directives/AreDirectiveShow.directive.d.ts +32 -0
- package/dist/node/directives/AreDirectiveShow.directive.js +81 -0
- package/dist/node/directives/AreDirectiveShow.directive.js.map +1 -0
- package/dist/node/directives/AreDirectiveShow.directive.mjs +71 -0
- package/dist/node/directives/AreDirectiveShow.directive.mjs.map +1 -0
- package/dist/node/engine/AreHTML.engine.d.mts +2 -1
- package/dist/node/engine/AreHTML.engine.d.ts +2 -1
- package/dist/node/engine/AreHTML.engine.js +8 -2
- package/dist/node/engine/AreHTML.engine.js.map +1 -1
- package/dist/node/engine/AreHTML.engine.mjs +8 -2
- package/dist/node/engine/AreHTML.engine.mjs.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.d.mts +3 -0
- package/dist/node/engine/AreHTML.interpreter.d.ts +3 -0
- package/dist/node/engine/AreHTML.interpreter.js +29 -0
- package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.mjs +29 -0
- package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
- package/dist/node/engine/AreHTML.lifecycle.d.mts +8 -1
- package/dist/node/engine/AreHTML.lifecycle.d.ts +8 -1
- package/dist/node/engine/AreHTML.lifecycle.js +46 -3
- package/dist/node/engine/AreHTML.lifecycle.js.map +1 -1
- package/dist/node/engine/AreHTML.lifecycle.mjs +46 -3
- package/dist/node/engine/AreHTML.lifecycle.mjs.map +1 -1
- package/dist/node/helpers/AreScheduler.helper.d.mts +39 -0
- package/dist/node/helpers/AreScheduler.helper.d.ts +39 -0
- package/dist/node/helpers/AreScheduler.helper.js +40 -0
- package/dist/node/helpers/AreScheduler.helper.js.map +1 -0
- package/dist/node/helpers/AreScheduler.helper.mjs +40 -0
- package/dist/node/helpers/AreScheduler.helper.mjs.map +1 -0
- package/dist/node/index.d.mts +4 -1
- package/dist/node/index.d.ts +4 -1
- package/dist/node/index.js +21 -0
- package/dist/node/index.mjs +3 -0
- package/dist/node/instructions/AreHTML.instructions.constants.d.mts +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.d.ts +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.js +2 -1
- package/dist/node/instructions/AreHTML.instructions.constants.js.map +1 -1
- package/dist/node/instructions/AreHTML.instructions.constants.mjs +2 -1
- package/dist/node/instructions/AreHTML.instructions.constants.mjs.map +1 -1
- package/dist/node/instructions/AreHTML.instructions.types.d.mts +9 -1
- package/dist/node/instructions/AreHTML.instructions.types.d.ts +9 -1
- package/dist/node/instructions/HideElement.instruction.d.mts +13 -0
- package/dist/node/instructions/HideElement.instruction.d.ts +13 -0
- package/dist/node/instructions/HideElement.instruction.js +31 -0
- package/dist/node/instructions/HideElement.instruction.js.map +1 -0
- package/dist/node/instructions/HideElement.instruction.mjs +24 -0
- package/dist/node/instructions/HideElement.instruction.mjs.map +1 -0
- package/dist/node/lib/AreRoot/AreRoot.component.d.mts +57 -3
- package/dist/node/lib/AreRoot/AreRoot.component.d.ts +57 -3
- package/dist/node/lib/AreRoot/AreRoot.component.js +138 -49
- package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
- package/dist/node/lib/AreRoot/AreRoot.component.mjs +140 -51
- package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
- package/dist/node/lib/AreRoot/AreRootCache.context.d.mts +58 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.d.ts +58 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.js +106 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.js.map +1 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.mjs +99 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.mjs.map +1 -0
- package/examples/dashboard/dist/index.html +1 -1
- package/examples/dashboard/dist/{mq19zxz4-mnlgmd.js → mqh9ryml-xat335.js} +1922 -1316
- package/examples/dashboard/src/concept.ts +3 -2
- package/examples/for-perf/concept.ts +45 -0
- package/examples/for-perf/containers/UI.container.ts +161 -0
- package/examples/for-perf/dist/index.html +270 -0
- package/examples/for-perf/dist/mqh9ryde-m243t8.js +15223 -0
- package/examples/for-perf/dist/mqh9ryfo-6a8d0o.js +15223 -0
- package/examples/for-perf/dist/mqh9ryfq-4pf5cv.js +15223 -0
- package/examples/for-perf/public/index.html +270 -0
- package/examples/for-perf/src/components/PerfApp.component.ts +37 -0
- package/examples/for-perf/src/components/PerfControls.component.ts +34 -0
- package/examples/for-perf/src/components/PerfGrid.component.ts +225 -0
- package/examples/for-perf/src/components/PerfHeader.component.ts +34 -0
- package/examples/for-perf/src/components/PerfStats.component.ts +43 -0
- package/examples/for-perf/src/concept.ts +94 -0
- package/examples/jumpstart/dist/index.html +1 -1
- package/examples/jumpstart/dist/{mq1a0fv0-ccgtz6.js → mq7mgf58-vbf07e.js} +895 -521
- package/examples/signal-routing/dist/index.html +1 -1
- package/examples/signal-routing/dist/{mq1bzrik-4lec86.js → mqh9ryc9-dkcbkx.js} +2024 -1300
- package/examples/signal-routing/src/components/SettingsPage.component.ts +39 -0
- package/examples/signal-routing/src/concept.ts +2 -0
- package/jest.config.ts +1 -0
- package/package.json +10 -9
- package/src/directives/AreDirectiveFor.directive.ts +185 -12
- package/src/directives/AreDirectiveShow.directive.ts +127 -0
- package/src/engine/AreHTML.engine.ts +11 -1
- package/src/engine/AreHTML.interpreter.ts +50 -0
- package/src/engine/AreHTML.lifecycle.ts +83 -6
- package/src/helpers/AreScheduler.helper.ts +61 -0
- package/src/index.ts +3 -0
- package/src/instructions/AreHTML.instructions.constants.ts +1 -0
- package/src/instructions/AreHTML.instructions.types.ts +9 -0
- package/src/instructions/HideElement.instruction.ts +29 -0
- package/src/lib/AreRoot/AreRoot.component.ts +205 -72
- package/src/lib/AreRoot/AreRootCache.context.ts +133 -0
- package/tsconfig.json +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/directives/AreDirectiveFor.directive.ts"],"names":[],"mappings":"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","file":"AreDirectiveFor.directive.mjs","sourcesContent":["import { A_Caller, A_Inject, A_Scope } from \"@adaas/a-concept\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { AreDirectiveAttribute } from \"@adaas/are-html/attributes/AreDirective.attribute\";\nimport { AreCompilerError, AreScene, AreStore } from \"@adaas/are\";\nimport { AreDirective } from \"@adaas/are-html/directive/AreDirective.component\";\nimport { AddCommentInstruction } from \"@adaas/are-html/instructions/AddComment.instruction\";\nimport { AreHTMLNode } from \"@adaas/are-html/node\";\nimport { AreDirectiveContext } from \"@adaas/are-html/directive/AreDirective.context\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\ntype AreForExpression = {\n key: string;\n index: string | undefined;\n arrayExpr: string;\n /** Optional `track <expr>` clause, e.g. `track row.id` */\n trackExpr: string | undefined;\n};\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Built-in $for directive. Iterates over an array expression resolved from the store and renders a cloned template fragment per item, managing per-item subscopes and comment-node anchors. Supports keyed diffing via an optional track clause to minimise DOM mutations on collection updates.'\n})\n@AreDirective.Priority(1)\nexport class AreDirectiveFor extends AreDirective {\n\n\n @AreDirective.Transform\n transform(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(A_Scope) scope: A_Scope,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n @A_Inject(A_Logger) logger: A_Logger,\n ...args: any[]\n ) {\n\n logger.debug(`[Transform] directive $FOR for <${attribute.owner.aseid.toString()}>`)\n\n const node = attribute.owner;\n\n /**\n * Transfer the original node's scope (with all registered attributes and children)\n * to the template clone, and give the owner node a fresh empty scope.\n * This mirrors the $if directive's approach, making the owner a lightweight\n * group container whose sole visible presence is a comment placeholder.\n */\n const forTemplate = node.cloneWithScope();\n\n /**\n * Remove the $for attribute from the template so iterative clones do not\n * re-trigger this directive during their own transform phase.\n * Re-register it on the owner so the reactive compile/update pipeline keeps working.\n */\n const forAttr = forTemplate.attributes.find(d => d.name === attribute.name);\n\n if (forAttr) {\n forTemplate.scope.deregister(forAttr);\n node.scope.register(forAttr);\n }\n\n /**\n * Re-initialize the owner node with its fresh scope so it becomes a valid\n * group container that will own the generated item nodes as children.\n */\n node.init();\n\n /**\n * Store the template for use in compile and update.\n */\n attribute.template = forTemplate;\n\n\n /**\n * Parse the $for expression and evaluate the source array.\n */\n const { key, index, arrayExpr } = this.parseExpression(attribute.content);\n const array = this.resolveArray(store, arrayExpr, attribute.content);\n\n attribute.value = array;\n\n /**\n * For each item in the array, spawn a clone of the template with the\n * item's store values pre-set and its scene activated.\n *\n * The children are added to the owner node before the main compiler's\n * children iteration loop runs, so the main cycle will compile them —\n * no explicit child.compile() call is needed here.\n */\n for (let i = 0; i < array.length; i++) {\n this.spawnItemNode(attribute.template!, attribute.owner, key, index, array[i], i);\n }\n }\n\n\n @AreDirective.Compile\n compile(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n ...args: any[]\n ): void {\n /**\n * Replace the group node's default host declaration with a comment placeholder\n * so the owner element itself does not render as a DOM element — the item nodes\n * render as its children instead.\n */\n const hostInstruction = scene.host!;\n const commentIdentifier = ` --- for: ${attribute.template!.id} --- `;\n const declaration = new AddCommentInstruction({ content: commentIdentifier });\n\n scene.setHost(declaration);\n scene.planBefore(declaration, hostInstruction);\n scene.unPlan(hostInstruction);\n }\n\n\n @AreDirective.Update\n update(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n ...args: any[]\n ): void {\n /**\n * Re-evaluate the source array.\n */\n const { key, index, arrayExpr, trackExpr } = this.parseExpression(attribute.content);\n const newArray = this.resolveArray(store, arrayExpr, attribute.content);\n\n const owner = attribute.owner;\n const currentChildren = [...owner.children] as AreHTMLNode[];\n\n attribute.value = newArray;\n\n const computeKey = this.makeKeyFn(key, index, trackExpr);\n\n // ── 1. Index existing children by stable key ────────────────────────\n const childByKey = new Map<any, AreHTMLNode>();\n const remaining = new Set<AreHTMLNode>();\n\n for (let i = 0; i < currentChildren.length; i++) {\n const child = currentChildren[i];\n const ctx = child.scope.resolveFlat(AreDirectiveContext);\n const k = ctx ? computeKey(ctx.scope[key], ctx.scope[index || 'index']) : Symbol('orphan');\n childByKey.set(k, child);\n remaining.add(child);\n }\n\n // ── 2. Walk desired list; reuse existing or spawn new ───────────────\n const desired: AreHTMLNode[] = [];\n const newOnes: AreHTMLNode[] = [];\n\n for (let i = 0; i < newArray.length; i++) {\n const item = newArray[i];\n const k = computeKey(item, i);\n const existing = childByKey.get(k);\n\n if (existing) {\n remaining.delete(existing);\n\n let directiveContext = existing.scope.resolveFlat(AreDirectiveContext);\n if (!directiveContext) {\n directiveContext = new AreDirectiveContext(existing.aseid);\n existing.scope.register(directiveContext);\n }\n directiveContext.scope = {\n ...directiveContext.scope,\n [key]: item,\n [index || 'index']: i,\n };\n desired.push(existing);\n } else {\n const itemNode = this.spawnItemNode(attribute.template!, owner, key, index, item, i);\n desired.push(itemNode);\n newOnes.push(itemNode);\n }\n }\n\n // ── 3. Unmount + detach removed children ─────────────────────────────\n for (const child of remaining) {\n child.unmount();\n owner.removeChild(child);\n }\n\n // ── 4. Mount only the new ones (kept children stay where they are). ─\n for (const child of newOnes) {\n child.transform();\n child.compile();\n child.mount();\n }\n }\n\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── Helpers ──────────────────────────────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Build a key-function that derives a stable identity from each item.\n * If the user provided a `track <expr>` clause, evaluate it as a path on\n * the item; otherwise fall back to the item identity (reference equality).\n */\n private makeKeyFn(key: string, index: string | undefined, trackExpr: string | undefined): (item: any, i: number) => any {\n if (!trackExpr) {\n return (item, i) => item ?? i;\n }\n\n // Strip any leading `key.` so users can write `track row.id`.\n const path = trackExpr.startsWith(key + '.') ? trackExpr.slice(key.length + 1) : trackExpr;\n\n return (item, i) => {\n if (item == null) return i;\n if (path === key || path === '$index') return path === '$index' ? i : item;\n\n // dotted path lookup\n const parts = path.split('.');\n let v: any = item;\n for (const p of parts) {\n if (v == null) return i;\n v = v[p];\n }\n return v ?? i;\n };\n }\n\n /**\n * Parses the $for expression string into its constituent parts.\n *\n * Supported formats:\n * item in items\n * item, index in items\n * (item, index) in items\n * item in filter(items)\n * item, index in filter(items, 'active')\n * item in items track item.id\n * (item, i) in items track item.id\n */\n private parseExpression(content: string): AreForExpression {\n // Strip optional `track <expr>` suffix first.\n let trackExpr: string | undefined;\n const trackIdx = content.search(/\\s+track\\s+/);\n let body = content;\n if (trackIdx !== -1) {\n const m = content.slice(trackIdx).match(/\\s+track\\s+(.+)$/);\n if (m) {\n trackExpr = m[1].trim();\n body = content.slice(0, trackIdx).trim();\n }\n }\n\n const inIndex = body.lastIndexOf(' in ');\n const keyAndIndex = body.slice(0, inIndex).trim().replace(/^\\(|\\)$/g, '');\n const arrayExpr = body.slice(inIndex + 4).trim();\n const keyParts = keyAndIndex.split(',').map(p => p.trim());\n\n return {\n key: keyParts[0],\n index: keyParts[1] || undefined,\n arrayExpr,\n trackExpr,\n };\n }\n\n /**\n * Resolves the array expression against the store.\n * Supports both plain key lookups and function-call expressions:\n * items → store.get('items')\n * filter(items) → store.get('filter')(store.get('items'))\n */\n private resolveArray(store: AreStore, arrayExpr: string, fullContent: string): any[] {\n let result: any;\n const callMatch = arrayExpr.match(/^([^(]+)\\((.+)\\)$/);\n\n if (callMatch) {\n const fnName = callMatch[1].trim();\n const fn = store.get(fnName as any);\n\n if (typeof fn !== 'function')\n throw new AreCompilerError({\n title: 'Invalid \"for\" Directive Function',\n description: `The expression \"${fnName}\" in the \"for\" directive does not resolve to a function in the store. Received: ${typeof fn}`,\n });\n\n const rawArgs = callMatch[2].split(',').map(a => a.trim());\n const resolvedArgs = rawArgs.map(arg => {\n if (arg.startsWith(\"'\") && arg.endsWith(\"'\")) return arg.slice(1, -1);\n if (arg.startsWith('\"') && arg.endsWith('\"')) return arg.slice(1, -1);\n if (!isNaN(Number(arg))) return Number(arg);\n // Dotted-path / optional-chain: e.g. `record?.embedding` or `record.data`\n const stripped = arg.replace(/\\?$/, '');\n if (stripped.includes('.')) {\n const parts = stripped.split('.').map(p => p.replace(/\\?$/, ''));\n let val: any = store.get(parts[0] as any);\n for (let j = 1; j < parts.length; j++) {\n if (val == null) return undefined;\n val = val[parts[j]];\n }\n return val ?? undefined;\n }\n return store.get(stripped as any);\n });\n\n result = (fn as Function)(...resolvedArgs);\n } else if (arrayExpr.includes('.')) {\n // dotted-path lookup: e.g. \"list.items\" or \"record?.keywords\"\n // Strip optional-chaining `?` suffix from each segment so that\n // `record?.keywords` resolves the same as `record.keywords`.\n const parts = arrayExpr.split('.').map(p => p.replace(/\\?$/, ''));\n result = store.get(parts[0] as any);\n for (let i = 1; i < parts.length; i++) {\n if (result == null) break;\n result = result[parts[i]];\n }\n } else {\n result = store.get(arrayExpr.replace(/\\?$/, '') as any);\n }\n\n // null / undefined from optional-chaining expressions (e.g. `record?.keywords`)\n // means the source object is not yet loaded — treat as empty array so the\n // directive initialises gracefully and fills in when the store updates.\n if (result == null) return [];\n\n if (!Array.isArray(result))\n throw new AreCompilerError({\n title: 'Invalid \"for\" Directive Value',\n description: `The \"for\" directive expects an array but got ${typeof result}. Expression: \"${fullContent}\". Received: ${JSON.stringify(result)}`,\n });\n\n return result;\n }\n\n /**\n * Creates a single item node from the template, registers it as a child of\n * the owner, initialises it, injects item-scoped store values, and activates\n * its scene so the mount/compile cycle will include it.\n *\n * NOTE: This method does NOT call compile() or mount() — the caller is\n * responsible for doing so when the main lifecycle cycle won't cover it\n * (i.e. during update, but not during the initial compile phase).\n */\n private spawnItemNode(\n template: AreHTMLNode,\n owner: AreHTMLNode,\n key: string,\n index: string | undefined,\n item: any,\n i: number,\n ): AreHTMLNode {\n const itemNode = template.clone() as AreHTMLNode;\n\n owner.addChild(itemNode);\n\n const queue = [itemNode];\n\n while (queue.length > 0) {\n const current = queue.shift()!\n\n current.init();\n\n queue.push(...current.children as AreHTMLNode[]);\n }\n\n /**\n * Resolve or create a directive context for the item node. This is needed to hold the item-specific store values (e.g. the \"item\" and \"index\" in a \"for\" loop) that the template's bindings will reference during compile and update. The context is shared among all clones of the same template, but that's fine because each clone gets its own scope values assigned here.\n */\n let directiveContext = itemNode.scope.resolveFlat(AreDirectiveContext);\n\n if (!directiveContext) {\n directiveContext = new AreDirectiveContext(itemNode.aseid);\n itemNode.scope.register(directiveContext);\n }\n\n directiveContext.scope = {\n ...directiveContext.scope,\n [key]: item,\n [index || 'index']: i,\n }\n\n itemNode.scene.activate();\n\n return itemNode;\n }\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/directives/AreDirectiveFor.directive.ts"],"names":[],"mappings":"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","file":"AreDirectiveFor.directive.mjs","sourcesContent":["import { A_Caller, A_Inject, A_Scope } from \"@adaas/a-concept\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { AreDirectiveAttribute } from \"@adaas/are-html/attributes/AreDirective.attribute\";\nimport { AreCompilerError, AreScene, AreStore } from \"@adaas/are\";\nimport { AreDirective } from \"@adaas/are-html/directive/AreDirective.component\";\nimport { AddCommentInstruction } from \"@adaas/are-html/instructions/AddComment.instruction\";\nimport { AreHTMLNode } from \"@adaas/are-html/node\";\nimport { AreDirectiveContext } from \"@adaas/are-html/directive/AreDirective.context\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\nimport { AreSchedulerHelper } from \"@adaas/are-html/helpers/AreScheduler.helper\";\n\n\ntype AreForExpression = {\n key: string;\n index: string | undefined;\n arrayExpr: string;\n /** Optional `track <expr>` clause, e.g. `track row.id` */\n trackExpr: string | undefined;\n};\n\n/**\n * Per-`$for` reentrancy state used to serialize chunked (async) renders.\n * Keyed by the directive attribute instance (one per `$for` in the template).\n */\ntype AreForRenderState = { running: boolean; pending: boolean };\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Built-in $for directive. Iterates over an array expression resolved from the store and renders a cloned template fragment per item, managing per-item subscopes and comment-node anchors. Supports keyed diffing via an optional track clause to minimise DOM mutations on collection updates.'\n})\n@AreDirective.Priority(1)\nexport class AreDirectiveFor extends AreDirective {\n\n /**\n * Lists whose number of NEW item nodes is at or below this threshold render\n * fully synchronously — byte-for-byte the previous behavior. Typical UIs\n * (menus, small tables) are therefore completely unaffected; only genuinely\n * large lists pay the (tiny) scheduling cost to keep the main thread responsive.\n */\n private static readonly SYNC_THRESHOLD = 100;\n\n /**\n * Per-chunk time budget (ms). During a large-list render we mount item nodes\n * until this much time has elapsed, then yield to the browser so it can paint\n * and process input before the next chunk. ~16ms targets one animation frame.\n */\n private static readonly CHUNK_BUDGET_MS = 16;\n\n /**\n * Per-attribute serialization state. A new update() that arrives while a\n * chunked render of the SAME `$for` is still in flight does NOT start a second\n * concurrent pass (which could interleave mutations on the shared children\n * list); instead it marks `pending` and the in-flight run re-runs once more\n * with the latest data when it finishes. This guarantees the children list is\n * only ever mutated by one pass at a time and the final state always reflects\n * the most recent store value.\n */\n private static readonly renderState = new WeakMap<object, AreForRenderState>();\n\n\n @AreDirective.Transform\n transform(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(A_Scope) scope: A_Scope,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n @A_Inject(A_Logger) logger: A_Logger,\n ...args: any[]\n ) {\n\n logger.debug(`[Transform] directive $FOR for <${attribute.owner.aseid.toString()}>`)\n\n const node = attribute.owner;\n\n /**\n * Transfer the original node's scope (with all registered attributes and children)\n * to the template clone, and give the owner node a fresh empty scope.\n * This mirrors the $if directive's approach, making the owner a lightweight\n * group container whose sole visible presence is a comment placeholder.\n */\n const forTemplate = node.cloneWithScope();\n\n /**\n * Remove the $for attribute from the template so iterative clones do not\n * re-trigger this directive during their own transform phase.\n * Re-register it on the owner so the reactive compile/update pipeline keeps working.\n */\n const forAttr = forTemplate.attributes.find(d => d.name === attribute.name);\n\n if (forAttr) {\n forTemplate.scope.deregister(forAttr);\n node.scope.register(forAttr);\n }\n\n /**\n * Re-initialize the owner node with its fresh scope so it becomes a valid\n * group container that will own the generated item nodes as children.\n */\n node.init();\n\n /**\n * Store the template for use in compile and update.\n */\n attribute.template = forTemplate;\n\n\n /**\n * Parse the $for expression and evaluate the source array.\n */\n const { key, index, arrayExpr } = this.parseExpression(attribute.content);\n const array = this.resolveArray(store, arrayExpr, attribute.content);\n\n attribute.value = array;\n\n /**\n * For each item in the array, spawn a clone of the template with the\n * item's store values pre-set and its scene activated.\n *\n * The children are added to the owner node before the main compiler's\n * children iteration loop runs, so the main cycle will compile them —\n * no explicit child.compile() call is needed here.\n */\n for (let i = 0; i < array.length; i++) {\n this.spawnItemNode(attribute.template!, attribute.owner, key, index, array[i], i);\n }\n }\n\n\n @AreDirective.Compile\n compile(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n ...args: any[]\n ): void {\n /**\n * Replace the group node's default host declaration with a comment placeholder\n * so the owner element itself does not render as a DOM element — the item nodes\n * render as its children instead.\n */\n const hostInstruction = scene.host!;\n const commentIdentifier = ` --- for: ${attribute.template!.id} --- `;\n const declaration = new AddCommentInstruction({ content: commentIdentifier });\n\n scene.setHost(declaration);\n scene.planBefore(declaration, hostInstruction);\n scene.unPlan(hostInstruction);\n }\n\n\n @AreDirective.Update\n update(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n ...args: any[]\n ): void | Promise<void> {\n /**\n * Serialize chunked renders per `$for`. If a previous large-list render\n * is still streaming item nodes across macrotasks, do NOT start a second\n * concurrent pass — that would interleave two diffs over the same shared\n * children list (and leave half-compiled item nodes that the next diff\n * would wrongly \"reuse\"). Mark a pass as pending instead; the in-flight\n * run re-diffs once more from the latest store value when it completes.\n */\n let state = AreDirectiveFor.renderState.get(attribute);\n if (!state) {\n state = { running: false, pending: false };\n AreDirectiveFor.renderState.set(attribute, state);\n }\n if (state.running) {\n state.pending = true;\n return;\n }\n\n return this.performUpdate(attribute, store, scene, state);\n }\n\n /**\n * Core of the `$for` update: re-diff the source array against the current\n * children, reconcile reused/removed items, then mount the new ones (small\n * lists synchronously, large lists time-sliced). Never called while another\n * pass for the same `$for` is in flight (see `update`).\n */\n private performUpdate(\n attribute: AreDirectiveAttribute,\n store: AreStore,\n scene: AreScene,\n state: AreForRenderState,\n ): void | Promise<void> {\n /**\n * Re-evaluate the source array.\n */\n const { key, index, arrayExpr, trackExpr } = this.parseExpression(attribute.content);\n const newArray = this.resolveArray(store, arrayExpr, attribute.content);\n\n const owner = attribute.owner;\n const currentChildren = [...owner.children] as AreHTMLNode[];\n\n attribute.value = newArray;\n\n /**\n * Is this `$for`'s subtree currently rendered into the DOM?\n *\n * A `$for` can update while its subtree is detached — e.g. it lives\n * inside a `$if` whose condition is currently false (the documented\n * `<div $if><x $for></div>` nesting). The directive still receives the\n * store change and re-diffs, but it must NOT mount/unmount item nodes\n * directly while detached: the `$for` anchor (and its ancestors) are\n * not in the DOM, so the interpreter's mount-point walk would fall\n * through to the nearest *mounted* ancestor (the `$if` comment in the\n * grandparent) and HOIST the items out of their intended container.\n * When the ancestor `$if` later activates, its mount cascade applies\n * the already-compiled item instructions in the correct place.\n *\n * Detached === any ancestor scene is inactive (regular nodes default\n * to an active scene; only structural directives deactivate one).\n */\n const attached = this.isAttached(owner);\n\n const computeKey = this.makeKeyFn(key, index, trackExpr);\n\n // ── 1. Index existing children by stable key ────────────────────────\n const childByKey = new Map<any, AreHTMLNode>();\n const remaining = new Set<AreHTMLNode>();\n\n for (let i = 0; i < currentChildren.length; i++) {\n const child = currentChildren[i];\n const ctx = child.scope.resolveFlat(AreDirectiveContext);\n const k = ctx ? computeKey(ctx.scope[key], ctx.scope[index || 'index']) : Symbol('orphan');\n childByKey.set(k, child);\n remaining.add(child);\n }\n\n // ── 2. Walk desired list; reuse existing or record items to create ──\n // NOTE: new item nodes are NOT spawned here. Spawning (cloneWithScope +\n // subtree init + scene activation) is the dominant cost of a large\n // render, so it is deferred into the time-sliced loop below alongside\n // transform/compile/mount. Existing (keyed) children are reconciled in\n // place synchronously — that is cheap and keeps reused rows stable.\n const toCreate: Array<{ item: any; idx: number }> = [];\n\n for (let i = 0; i < newArray.length; i++) {\n const item = newArray[i];\n const k = computeKey(item, i);\n const existing = childByKey.get(k);\n\n if (existing) {\n remaining.delete(existing);\n\n let directiveContext = existing.scope.resolveFlat(AreDirectiveContext);\n if (!directiveContext) {\n directiveContext = new AreDirectiveContext(existing.aseid);\n existing.scope.register(directiveContext);\n }\n directiveContext.scope = {\n ...directiveContext.scope,\n [key]: item,\n [index || 'index']: i,\n };\n } else {\n toCreate.push({ item, idx: i });\n }\n }\n\n // ── 3. Unmount + detach removed children ─────────────────────────────\n for (const child of remaining) {\n // Only revert DOM if the subtree is live; a detached subtree's item\n // nodes were never mounted (see `attached` rationale above), so\n // unmounting them is a no-op at best and risks reverting stale state.\n if (attached) child.unmount();\n owner.removeChild(child);\n }\n\n // ── 4. Create + mount the new item nodes. ───────────────────────────\n // `spawnItemNode` appends to `owner.children` immediately, so iterating\n // `toCreate` in source order preserves list order (reused children keep\n // their positions, new rows are appended in order) — identical to the\n // previous synchronous behavior.\n const createItem = (desc: { item: any; idx: number }) => {\n const child = this.spawnItemNode(attribute.template!, owner, key, index, desc.item, desc.idx);\n child.transform();\n child.compile();\n // While detached, stop after compile: the item's instructions are\n // planned and the ancestor `$if`'s mount cascade will apply them in\n // the correct container once the condition becomes truthy. Mounting\n // here would hoist the item to the nearest mounted ancestor.\n if (attached) child.mount();\n };\n\n // Small lists → fully synchronous, identical to the previous behavior.\n if (toCreate.length <= AreDirectiveFor.SYNC_THRESHOLD) {\n for (const desc of toCreate) createItem(desc);\n return this.finishUpdate(attribute, store, scene, state);\n }\n\n // Large lists → time-sliced render. Create item nodes until the frame\n // budget elapses, then yield to the browser (zero-delay macrotask) so\n // it can paint and stay responsive instead of blocking for the whole\n // batch. The `state.running` flag (see `update`) prevents any other\n // update() for this `$for` from interleaving while we stream.\n state.running = true;\n let cursor = 0;\n\n const processChunk = (): void | Promise<void> => {\n try {\n const start = AreSchedulerHelper.now();\n while (cursor < toCreate.length) {\n createItem(toCreate[cursor]);\n cursor++;\n if (AreSchedulerHelper.now() - start >= AreDirectiveFor.CHUNK_BUDGET_MS) break;\n }\n } catch (error) {\n // Never leave the `$for` wedged in the running state on failure,\n // or every future update would be silently deferred forever.\n state.running = false;\n state.pending = false;\n throw error;\n }\n\n if (cursor < toCreate.length) {\n return new Promise<void>(resolve => {\n AreSchedulerHelper.scheduleMacrotask(() => resolve(processChunk()));\n });\n }\n\n return this.finishUpdate(attribute, store, scene, state);\n };\n\n return processChunk();\n }\n\n /**\n * Completes an update pass. If another update() arrived while a chunked\n * render was streaming, run exactly one more pass now from the latest store\n * value so the final DOM always reflects the most recent data.\n */\n private finishUpdate(\n attribute: AreDirectiveAttribute,\n store: AreStore,\n scene: AreScene,\n state: AreForRenderState,\n ): void | Promise<void> {\n state.running = false;\n if (state.pending) {\n state.pending = false;\n return this.performUpdate(attribute, store, scene, state);\n }\n }\n\n\n /**\n * Walks the node's ancestor chain (inclusive) and reports whether the\n * whole path is currently active — i.e. the subtree is actually rendered\n * into the DOM. A single inactive ancestor scene (e.g. a `$if` whose\n * condition is false) means the subtree is detached.\n */\n private isAttached(node: AreHTMLNode): boolean {\n let current: AreHTMLNode | undefined = node;\n while (current) {\n if (current.scene?.isInactive) return false;\n current = current.parent as AreHTMLNode | undefined;\n }\n return true;\n }\n\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── Helpers ──────────────────────────────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Build a key-function that derives a stable identity from each item.\n * If the user provided a `track <expr>` clause, evaluate it as a path on\n * the item; otherwise fall back to the item identity (reference equality).\n */\n private makeKeyFn(key: string, index: string | undefined, trackExpr: string | undefined): (item: any, i: number) => any {\n if (!trackExpr) {\n return (item, i) => item ?? i;\n }\n\n // Strip any leading `key.` so users can write `track row.id`.\n const path = trackExpr.startsWith(key + '.') ? trackExpr.slice(key.length + 1) : trackExpr;\n\n return (item, i) => {\n if (item == null) return i;\n if (path === key || path === '$index') return path === '$index' ? i : item;\n\n // dotted path lookup\n const parts = path.split('.');\n let v: any = item;\n for (const p of parts) {\n if (v == null) return i;\n v = v[p];\n }\n return v ?? i;\n };\n }\n\n /**\n * Parses the $for expression string into its constituent parts.\n *\n * Supported formats:\n * item in items\n * item, index in items\n * (item, index) in items\n * item in filter(items)\n * item, index in filter(items, 'active')\n * item in items track item.id\n * (item, i) in items track item.id\n */\n private parseExpression(content: string): AreForExpression {\n // Strip optional `track <expr>` suffix first.\n let trackExpr: string | undefined;\n const trackIdx = content.search(/\\s+track\\s+/);\n let body = content;\n if (trackIdx !== -1) {\n const m = content.slice(trackIdx).match(/\\s+track\\s+(.+)$/);\n if (m) {\n trackExpr = m[1].trim();\n body = content.slice(0, trackIdx).trim();\n }\n }\n\n const inIndex = body.lastIndexOf(' in ');\n const keyAndIndex = body.slice(0, inIndex).trim().replace(/^\\(|\\)$/g, '');\n const arrayExpr = body.slice(inIndex + 4).trim();\n const keyParts = keyAndIndex.split(',').map(p => p.trim());\n\n return {\n key: keyParts[0],\n index: keyParts[1] || undefined,\n arrayExpr,\n trackExpr,\n };\n }\n\n /**\n * Resolves the array expression against the store.\n * Supports both plain key lookups and function-call expressions:\n * items → store.get('items')\n * filter(items) → store.get('filter')(store.get('items'))\n */\n private resolveArray(store: AreStore, arrayExpr: string, fullContent: string): any[] {\n let result: any;\n const callMatch = arrayExpr.match(/^([^(]+)\\((.+)\\)$/);\n\n if (callMatch) {\n const fnName = callMatch[1].trim();\n const fn = store.get(fnName as any);\n\n if (typeof fn !== 'function')\n throw new AreCompilerError({\n title: 'Invalid \"for\" Directive Function',\n description: `The expression \"${fnName}\" in the \"for\" directive does not resolve to a function in the store. Received: ${typeof fn}`,\n });\n\n const rawArgs = callMatch[2].split(',').map(a => a.trim());\n const resolvedArgs = rawArgs.map(arg => {\n if (arg.startsWith(\"'\") && arg.endsWith(\"'\")) return arg.slice(1, -1);\n if (arg.startsWith('\"') && arg.endsWith('\"')) return arg.slice(1, -1);\n if (!isNaN(Number(arg))) return Number(arg);\n // Dotted-path / optional-chain: e.g. `record?.embedding` or `record.data`\n const stripped = arg.replace(/\\?$/, '');\n if (stripped.includes('.')) {\n const parts = stripped.split('.').map(p => p.replace(/\\?$/, ''));\n let val: any = store.get(parts[0] as any);\n for (let j = 1; j < parts.length; j++) {\n if (val == null) return undefined;\n val = val[parts[j]];\n }\n return val ?? undefined;\n }\n return store.get(stripped as any);\n });\n\n result = (fn as Function)(...resolvedArgs);\n } else if (arrayExpr.includes('.')) {\n // dotted-path lookup: e.g. \"list.items\" or \"record?.keywords\"\n // Strip optional-chaining `?` suffix from each segment so that\n // `record?.keywords` resolves the same as `record.keywords`.\n const parts = arrayExpr.split('.').map(p => p.replace(/\\?$/, ''));\n result = store.get(parts[0] as any);\n for (let i = 1; i < parts.length; i++) {\n if (result == null) break;\n result = result[parts[i]];\n }\n } else {\n result = store.get(arrayExpr.replace(/\\?$/, '') as any);\n }\n\n // null / undefined from optional-chaining expressions (e.g. `record?.keywords`)\n // means the source object is not yet loaded — treat as empty array so the\n // directive initialises gracefully and fills in when the store updates.\n if (result == null) return [];\n\n if (!Array.isArray(result))\n throw new AreCompilerError({\n title: 'Invalid \"for\" Directive Value',\n description: `The \"for\" directive expects an array but got ${typeof result}. Expression: \"${fullContent}\". Received: ${JSON.stringify(result)}`,\n });\n\n return result;\n }\n\n /**\n * Creates a single item node from the template, registers it as a child of\n * the owner, initialises it, injects item-scoped store values, and activates\n * its scene so the mount/compile cycle will include it.\n *\n * NOTE: This method does NOT call compile() or mount() — the caller is\n * responsible for doing so when the main lifecycle cycle won't cover it\n * (i.e. during update, but not during the initial compile phase).\n */\n private spawnItemNode(\n template: AreHTMLNode,\n owner: AreHTMLNode,\n key: string,\n index: string | undefined,\n item: any,\n i: number,\n ): AreHTMLNode {\n const itemNode = template.clone() as AreHTMLNode;\n\n owner.addChild(itemNode);\n\n const queue = [itemNode];\n\n while (queue.length > 0) {\n const current = queue.shift()!\n\n current.init();\n\n queue.push(...current.children as AreHTMLNode[]);\n }\n\n /**\n * Resolve or create a directive context for the item node. This is needed to hold the item-specific store values (e.g. the \"item\" and \"index\" in a \"for\" loop) that the template's bindings will reference during compile and update. The context is shared among all clones of the same template, but that's fine because each clone gets its own scope values assigned here.\n */\n let directiveContext = itemNode.scope.resolveFlat(AreDirectiveContext);\n\n if (!directiveContext) {\n directiveContext = new AreDirectiveContext(itemNode.aseid);\n itemNode.scope.register(directiveContext);\n }\n\n directiveContext.scope = {\n ...directiveContext.scope,\n [key]: item,\n [index || 'index']: i,\n }\n\n itemNode.scene.activate();\n\n return itemNode;\n }\n}"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { A_Logger } from '@adaas/a-utils/a-logger';
|
|
2
|
+
import { a as AreDirective, b as AreDirectiveAttribute } from '../AreBinding.attribute-doUvtOjc.mjs';
|
|
3
|
+
import { AreStore, AreScene, AreSyntax } from '@adaas/are';
|
|
4
|
+
import { AreDirectiveContext } from '../lib/AreDirective/AreDirective.context.mjs';
|
|
5
|
+
import '@adaas/a-concept';
|
|
6
|
+
import '../lib/AreStyle/AreStyle.context.mjs';
|
|
7
|
+
import '@adaas/a-utils/a-execution';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `$show` directive — conditionally toggles an element's visibility.
|
|
11
|
+
*
|
|
12
|
+
* Unlike `$if`, `$show` keeps the element fully mounted at all times and only
|
|
13
|
+
* flips its inline `display` (Vue `v-show` semantics). The element's subtree,
|
|
14
|
+
* event listeners and scene state are preserved across toggles, which makes it
|
|
15
|
+
* far cheaper than `$if` for things that flip on/off frequently. Use `$if` when
|
|
16
|
+
* the hidden branch is expensive and rarely shown; use `$show` when it toggles
|
|
17
|
+
* often.
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ Known limitations:
|
|
20
|
+
* - Do NOT combine `$show` with `$if`/`$for` on the SAME element — they share
|
|
21
|
+
* an owner node and would fight over its host instruction. Wrap one in a
|
|
22
|
+
* parent element instead.
|
|
23
|
+
* - `$show` forces inline `display:none`, which beats stylesheet rules but will
|
|
24
|
+
* NOT override the element's own inline `:style="display:..."` binding.
|
|
25
|
+
*/
|
|
26
|
+
declare class AreDirectiveShow extends AreDirective {
|
|
27
|
+
transform(attribute: AreDirectiveAttribute, logger: A_Logger, ...args: any[]): void;
|
|
28
|
+
compile(attribute: AreDirectiveAttribute, store: AreStore, scene: AreScene, syntax: AreSyntax, directiveContext?: AreDirectiveContext, ...args: any[]): void;
|
|
29
|
+
update(attribute: AreDirectiveAttribute, store: AreStore, scene: AreScene, syntax: AreSyntax, directiveContext?: AreDirectiveContext, ...args: any[]): void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { AreDirectiveShow };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { A_Logger } from '@adaas/a-utils/a-logger';
|
|
2
|
+
import { a as AreDirective, b as AreDirectiveAttribute } from '../AreBinding.attribute-Bm5LlOyE.js';
|
|
3
|
+
import { AreStore, AreScene, AreSyntax } from '@adaas/are';
|
|
4
|
+
import { AreDirectiveContext } from '../lib/AreDirective/AreDirective.context.js';
|
|
5
|
+
import '@adaas/a-concept';
|
|
6
|
+
import '../lib/AreStyle/AreStyle.context.js';
|
|
7
|
+
import '@adaas/a-utils/a-execution';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `$show` directive — conditionally toggles an element's visibility.
|
|
11
|
+
*
|
|
12
|
+
* Unlike `$if`, `$show` keeps the element fully mounted at all times and only
|
|
13
|
+
* flips its inline `display` (Vue `v-show` semantics). The element's subtree,
|
|
14
|
+
* event listeners and scene state are preserved across toggles, which makes it
|
|
15
|
+
* far cheaper than `$if` for things that flip on/off frequently. Use `$if` when
|
|
16
|
+
* the hidden branch is expensive and rarely shown; use `$show` when it toggles
|
|
17
|
+
* often.
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ Known limitations:
|
|
20
|
+
* - Do NOT combine `$show` with `$if`/`$for` on the SAME element — they share
|
|
21
|
+
* an owner node and would fight over its host instruction. Wrap one in a
|
|
22
|
+
* parent element instead.
|
|
23
|
+
* - `$show` forces inline `display:none`, which beats stylesheet rules but will
|
|
24
|
+
* NOT override the element's own inline `:style="display:..."` binding.
|
|
25
|
+
*/
|
|
26
|
+
declare class AreDirectiveShow extends AreDirective {
|
|
27
|
+
transform(attribute: AreDirectiveAttribute, logger: A_Logger, ...args: any[]): void;
|
|
28
|
+
compile(attribute: AreDirectiveAttribute, store: AreStore, scene: AreScene, syntax: AreSyntax, directiveContext?: AreDirectiveContext, ...args: any[]): void;
|
|
29
|
+
update(attribute: AreDirectiveAttribute, store: AreStore, scene: AreScene, syntax: AreSyntax, directiveContext?: AreDirectiveContext, ...args: any[]): void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { AreDirectiveShow };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var aConcept = require('@adaas/a-concept');
|
|
4
|
+
var aLogger = require('@adaas/a-utils/a-logger');
|
|
5
|
+
var are = require('@adaas/are');
|
|
6
|
+
var AreDirective_component = require('@adaas/are-html/directive/AreDirective.component');
|
|
7
|
+
var AreDirective_context = require('@adaas/are-html/directive/AreDirective.context');
|
|
8
|
+
var HideElement_instruction = require('@adaas/are-html/instructions/HideElement.instruction');
|
|
9
|
+
var core = require('@adaas/a-frame/core');
|
|
10
|
+
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
14
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
15
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
16
|
+
if (decorator = decorators[i])
|
|
17
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
18
|
+
if (kind && result) __defProp(target, key, result);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
22
|
+
exports.AreDirectiveShow = class AreDirectiveShow extends AreDirective_component.AreDirective {
|
|
23
|
+
transform(attribute, logger, ...args) {
|
|
24
|
+
logger.debug(`[Transform] directive $SHOW for <${attribute.owner.aseid.toString()}> (no structural change)`);
|
|
25
|
+
}
|
|
26
|
+
compile(attribute, store, scene, syntax, directiveContext, ...args) {
|
|
27
|
+
const visible = !!syntax.evaluate(attribute.content, store, {
|
|
28
|
+
...directiveContext?.scope || {}
|
|
29
|
+
});
|
|
30
|
+
attribute.value = visible;
|
|
31
|
+
const hide = new HideElement_instruction.HideElementInstruction(scene.host, {});
|
|
32
|
+
attribute.cache = hide;
|
|
33
|
+
if (!visible)
|
|
34
|
+
scene.plan(hide);
|
|
35
|
+
}
|
|
36
|
+
update(attribute, store, scene, syntax, directiveContext, ...args) {
|
|
37
|
+
const previous = !!attribute.value;
|
|
38
|
+
const next = !!syntax.evaluate(attribute.content, store, {
|
|
39
|
+
...directiveContext?.scope || {}
|
|
40
|
+
});
|
|
41
|
+
attribute.value = next;
|
|
42
|
+
if (previous === next) return;
|
|
43
|
+
const hide = attribute.cache;
|
|
44
|
+
if (!hide) return;
|
|
45
|
+
if (next)
|
|
46
|
+
scene.unPlan(hide);
|
|
47
|
+
else
|
|
48
|
+
scene.plan(hide);
|
|
49
|
+
attribute.owner.interpret();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
__decorateClass([
|
|
53
|
+
AreDirective_component.AreDirective.Transform,
|
|
54
|
+
__decorateParam(0, aConcept.A_Inject(aConcept.A_Caller)),
|
|
55
|
+
__decorateParam(1, aConcept.A_Inject(aLogger.A_Logger))
|
|
56
|
+
], exports.AreDirectiveShow.prototype, "transform", 1);
|
|
57
|
+
__decorateClass([
|
|
58
|
+
AreDirective_component.AreDirective.Compile,
|
|
59
|
+
__decorateParam(0, aConcept.A_Inject(aConcept.A_Caller)),
|
|
60
|
+
__decorateParam(1, aConcept.A_Inject(are.AreStore)),
|
|
61
|
+
__decorateParam(2, aConcept.A_Inject(are.AreScene)),
|
|
62
|
+
__decorateParam(3, aConcept.A_Inject(are.AreSyntax)),
|
|
63
|
+
__decorateParam(4, aConcept.A_Inject(AreDirective_context.AreDirectiveContext))
|
|
64
|
+
], exports.AreDirectiveShow.prototype, "compile", 1);
|
|
65
|
+
__decorateClass([
|
|
66
|
+
AreDirective_component.AreDirective.Update,
|
|
67
|
+
__decorateParam(0, aConcept.A_Inject(aConcept.A_Caller)),
|
|
68
|
+
__decorateParam(1, aConcept.A_Inject(are.AreStore)),
|
|
69
|
+
__decorateParam(2, aConcept.A_Inject(are.AreScene)),
|
|
70
|
+
__decorateParam(3, aConcept.A_Inject(are.AreSyntax)),
|
|
71
|
+
__decorateParam(4, aConcept.A_Inject(AreDirective_context.AreDirectiveContext))
|
|
72
|
+
], exports.AreDirectiveShow.prototype, "update", 1);
|
|
73
|
+
exports.AreDirectiveShow = __decorateClass([
|
|
74
|
+
core.A_Frame.Define({
|
|
75
|
+
namespace: "a-are-html",
|
|
76
|
+
description: "Built-in $show directive. Toggles an element's visibility by flipping its inline display value based on a store expression, keeping the element mounted (subtree, listeners and scene state preserved) instead of unmounting it like $if."
|
|
77
|
+
}),
|
|
78
|
+
AreDirective_component.AreDirective.Priority(3)
|
|
79
|
+
], exports.AreDirectiveShow);
|
|
80
|
+
//# sourceMappingURL=AreDirectiveShow.directive.js.map
|
|
81
|
+
//# sourceMappingURL=AreDirectiveShow.directive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/directives/AreDirectiveShow.directive.ts"],"names":["AreDirectiveShow","AreDirective","HideElementInstruction","A_Caller","A_Logger","AreStore","AreScene","AreSyntax","AreDirectiveContext","A_Frame"],"mappings":"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","file":"AreDirectiveShow.directive.js","sourcesContent":["import { A_Caller, A_Inject } from \"@adaas/a-concept\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { AreDirectiveAttribute } from \"@adaas/are-html/attributes/AreDirective.attribute\";\nimport { AreScene, AreStore, AreSyntax } from \"@adaas/are\";\nimport { AreDirective } from \"@adaas/are-html/directive/AreDirective.component\";\nimport { AreDirectiveContext } from \"@adaas/are-html/directive/AreDirective.context\";\nimport { HideElementInstruction } from \"@adaas/are-html/instructions/HideElement.instruction\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n\n/**\n * `$show` directive — conditionally toggles an element's visibility.\n *\n * Unlike `$if`, `$show` keeps the element fully mounted at all times and only\n * flips its inline `display` (Vue `v-show` semantics). The element's subtree,\n * event listeners and scene state are preserved across toggles, which makes it\n * far cheaper than `$if` for things that flip on/off frequently. Use `$if` when\n * the hidden branch is expensive and rarely shown; use `$show` when it toggles\n * often.\n *\n * ⚠️ Known limitations:\n * - Do NOT combine `$show` with `$if`/`$for` on the SAME element — they share\n * an owner node and would fight over its host instruction. Wrap one in a\n * parent element instead.\n * - `$show` forces inline `display:none`, which beats stylesheet rules but will\n * NOT override the element's own inline `:style=\"display:...\"` binding.\n */\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Built-in $show directive. Toggles an element\\'s visibility by flipping its inline display value based on a store expression, keeping the element mounted (subtree, listeners and scene state preserved) instead of unmounting it like $if.'\n})\n@AreDirective.Priority(3)\nexport class AreDirectiveShow extends AreDirective {\n\n\n @AreDirective.Transform\n transform(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(A_Logger) logger: A_Logger,\n ...args: any[]\n ) {\n // $show makes no structural change to the tree — the element stays in\n // place and is only hidden/shown at interpret time. Nothing to do here\n // beyond overriding the base directive's default transform warning.\n logger.debug(`[Transform] directive $SHOW for <${attribute.owner.aseid.toString()}> (no structural change)`)\n }\n\n\n @AreDirective.Compile\n compile(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n @A_Inject(AreSyntax) syntax: AreSyntax,\n\n @A_Inject(AreDirectiveContext) directiveContext?: AreDirectiveContext,\n ...args: any[]\n ): void {\n /**\n * 1. Evaluate the expression to determine the initial visibility.\n */\n const visible = !!syntax.evaluate(attribute.content, store, {\n ...(directiveContext?.scope || {}),\n });\n\n attribute.value = visible;\n\n /**\n * 2. Create a single reusable HideElement mutation parented to the\n * element's host instruction, and cache it on the attribute so\n * update() can plan/unplan the exact same instance.\n */\n const hide = new HideElementInstruction(scene.host!, {});\n attribute.cache = hide;\n\n /**\n * 3. When initially hidden, plan the mutation so the first interpret\n * applies `display:none`. When visible, leave it unplanned.\n */\n if (!visible)\n scene.plan(hide);\n }\n\n\n @AreDirective.Update\n update(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n @A_Inject(AreSyntax) syntax: AreSyntax,\n\n @A_Inject(AreDirectiveContext) directiveContext?: AreDirectiveContext,\n ...args: any[]\n ): void {\n /**\n * 1. Re-evaluate the expression, forwarding the directive context scope\n * (e.g. a `$for` loop variable) so `$show` reacts correctly inside\n * loops.\n */\n const previous = !!attribute.value;\n const next = !!syntax.evaluate(attribute.content, store, {\n ...(directiveContext?.scope || {}),\n });\n\n attribute.value = next;\n\n // Skip when visibility has not changed — avoids redundant DOM writes.\n if (previous === next) return;\n\n const hide = attribute.cache as HideElementInstruction | undefined;\n\n if (!hide) return;\n\n /**\n * 2. Toggle the cached mutation: unplan to reveal, plan to hide. Then\n * re-interpret the owner so the scene diff applies/reverts it.\n */\n if (next)\n scene.unPlan(hide);\n else\n scene.plan(hide);\n\n attribute.owner.interpret();\n }\n\n}\n"]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { __decorateClass, __decorateParam } from '../chunk-EQQGB2QZ.mjs';
|
|
2
|
+
import { A_Inject, A_Caller } from '@adaas/a-concept';
|
|
3
|
+
import { A_Logger } from '@adaas/a-utils/a-logger';
|
|
4
|
+
import { AreStore, AreScene, AreSyntax } from '@adaas/are';
|
|
5
|
+
import { AreDirective } from '@adaas/are-html/directive/AreDirective.component';
|
|
6
|
+
import { AreDirectiveContext } from '@adaas/are-html/directive/AreDirective.context';
|
|
7
|
+
import { HideElementInstruction } from '@adaas/are-html/instructions/HideElement.instruction';
|
|
8
|
+
import { A_Frame } from '@adaas/a-frame/core';
|
|
9
|
+
|
|
10
|
+
let AreDirectiveShow = class extends AreDirective {
|
|
11
|
+
transform(attribute, logger, ...args) {
|
|
12
|
+
logger.debug(`[Transform] directive $SHOW for <${attribute.owner.aseid.toString()}> (no structural change)`);
|
|
13
|
+
}
|
|
14
|
+
compile(attribute, store, scene, syntax, directiveContext, ...args) {
|
|
15
|
+
const visible = !!syntax.evaluate(attribute.content, store, {
|
|
16
|
+
...directiveContext?.scope || {}
|
|
17
|
+
});
|
|
18
|
+
attribute.value = visible;
|
|
19
|
+
const hide = new HideElementInstruction(scene.host, {});
|
|
20
|
+
attribute.cache = hide;
|
|
21
|
+
if (!visible)
|
|
22
|
+
scene.plan(hide);
|
|
23
|
+
}
|
|
24
|
+
update(attribute, store, scene, syntax, directiveContext, ...args) {
|
|
25
|
+
const previous = !!attribute.value;
|
|
26
|
+
const next = !!syntax.evaluate(attribute.content, store, {
|
|
27
|
+
...directiveContext?.scope || {}
|
|
28
|
+
});
|
|
29
|
+
attribute.value = next;
|
|
30
|
+
if (previous === next) return;
|
|
31
|
+
const hide = attribute.cache;
|
|
32
|
+
if (!hide) return;
|
|
33
|
+
if (next)
|
|
34
|
+
scene.unPlan(hide);
|
|
35
|
+
else
|
|
36
|
+
scene.plan(hide);
|
|
37
|
+
attribute.owner.interpret();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
__decorateClass([
|
|
41
|
+
AreDirective.Transform,
|
|
42
|
+
__decorateParam(0, A_Inject(A_Caller)),
|
|
43
|
+
__decorateParam(1, A_Inject(A_Logger))
|
|
44
|
+
], AreDirectiveShow.prototype, "transform", 1);
|
|
45
|
+
__decorateClass([
|
|
46
|
+
AreDirective.Compile,
|
|
47
|
+
__decorateParam(0, A_Inject(A_Caller)),
|
|
48
|
+
__decorateParam(1, A_Inject(AreStore)),
|
|
49
|
+
__decorateParam(2, A_Inject(AreScene)),
|
|
50
|
+
__decorateParam(3, A_Inject(AreSyntax)),
|
|
51
|
+
__decorateParam(4, A_Inject(AreDirectiveContext))
|
|
52
|
+
], AreDirectiveShow.prototype, "compile", 1);
|
|
53
|
+
__decorateClass([
|
|
54
|
+
AreDirective.Update,
|
|
55
|
+
__decorateParam(0, A_Inject(A_Caller)),
|
|
56
|
+
__decorateParam(1, A_Inject(AreStore)),
|
|
57
|
+
__decorateParam(2, A_Inject(AreScene)),
|
|
58
|
+
__decorateParam(3, A_Inject(AreSyntax)),
|
|
59
|
+
__decorateParam(4, A_Inject(AreDirectiveContext))
|
|
60
|
+
], AreDirectiveShow.prototype, "update", 1);
|
|
61
|
+
AreDirectiveShow = __decorateClass([
|
|
62
|
+
A_Frame.Define({
|
|
63
|
+
namespace: "a-are-html",
|
|
64
|
+
description: "Built-in $show directive. Toggles an element's visibility by flipping its inline display value based on a store expression, keeping the element mounted (subtree, listeners and scene state preserved) instead of unmounting it like $if."
|
|
65
|
+
}),
|
|
66
|
+
AreDirective.Priority(3)
|
|
67
|
+
], AreDirectiveShow);
|
|
68
|
+
|
|
69
|
+
export { AreDirectiveShow };
|
|
70
|
+
//# sourceMappingURL=AreDirectiveShow.directive.mjs.map
|
|
71
|
+
//# sourceMappingURL=AreDirectiveShow.directive.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/directives/AreDirectiveShow.directive.ts"],"names":[],"mappings":";;;;;;;;;AAiCO,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAA,EAI/C,SAAA,CACwB,SAAA,EACA,MAAA,EAAA,GACjB,IAAA,EACL;AAIE,IAAA,MAAA,CAAO,MAAM,CAAA,iCAAA,EAAoC,SAAA,CAAU,MAAM,KAAA,CAAM,QAAA,EAAU,CAAA,wBAAA,CAA0B,CAAA;AAAA,EAC/G;AAAA,EAIA,QACwB,SAAA,EACA,KAAA,EACA,KAAA,EACC,MAAA,EAEU,qBAC5B,IAAA,EACC;AAIJ,IAAA,MAAM,UAAU,CAAC,CAAC,OAAO,QAAA,CAAS,SAAA,CAAU,SAAS,KAAA,EAAO;AAAA,MACxD,GAAI,gBAAA,EAAkB,KAAA,IAAS;AAAC,KACnC,CAAA;AAED,IAAA,SAAA,CAAU,KAAA,GAAQ,OAAA;AAOlB,IAAA,MAAM,OAAO,IAAI,sBAAA,CAAuB,KAAA,CAAM,IAAA,EAAO,EAAE,CAAA;AACvD,IAAA,SAAA,CAAU,KAAA,GAAQ,IAAA;AAMlB,IAAA,IAAI,CAAC,OAAA;AACD,MAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EACvB;AAAA,EAIA,OACwB,SAAA,EACA,KAAA,EACA,KAAA,EACC,MAAA,EAEU,qBAC5B,IAAA,EACC;AAMJ,IAAA,MAAM,QAAA,GAAW,CAAC,CAAC,SAAA,CAAU,KAAA;AAC7B,IAAA,MAAM,OAAO,CAAC,CAAC,OAAO,QAAA,CAAS,SAAA,CAAU,SAAS,KAAA,EAAO;AAAA,MACrD,GAAI,gBAAA,EAAkB,KAAA,IAAS;AAAC,KACnC,CAAA;AAED,IAAA,SAAA,CAAU,KAAA,GAAQ,IAAA;AAGlB,IAAA,IAAI,aAAa,IAAA,EAAM;AAEvB,IAAA,MAAM,OAAO,SAAA,CAAU,KAAA;AAEvB,IAAA,IAAI,CAAC,IAAA,EAAM;AAMX,IAAA,IAAI,IAAA;AACA,MAAA,KAAA,CAAM,OAAO,IAAI,CAAA;AAAA;AAEjB,MAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAEnB,IAAA,SAAA,CAAU,MAAM,SAAA,EAAU;AAAA,EAC9B;AAEJ;AAzFI,eAAA,CAAA;AAAA,EADC,YAAA,CAAa,SAAA;AAAA,EAET,4BAAS,QAAQ,CAAA,CAAA;AAAA,EACjB,4BAAS,QAAQ,CAAA;AAAA,CAAA,EANb,gBAAA,CAIT,SAAA,EAAA,WAAA,EAAA,CAAA,CAAA;AAaA,eAAA,CAAA;AAAA,EADC,YAAA,CAAa,OAAA;AAAA,EAET,4BAAS,QAAQ,CAAA,CAAA;AAAA,EACjB,4BAAS,QAAQ,CAAA,CAAA;AAAA,EACjB,4BAAS,QAAQ,CAAA,CAAA;AAAA,EACjB,4BAAS,SAAS,CAAA,CAAA;AAAA,EAElB,4BAAS,mBAAmB,CAAA;AAAA,CAAA,EAvBxB,gBAAA,CAiBT,SAAA,EAAA,SAAA,EAAA,CAAA,CAAA;AAoCA,eAAA,CAAA;AAAA,EADC,YAAA,CAAa,MAAA;AAAA,EAET,4BAAS,QAAQ,CAAA,CAAA;AAAA,EACjB,4BAAS,QAAQ,CAAA,CAAA;AAAA,EACjB,4BAAS,QAAQ,CAAA,CAAA;AAAA,EACjB,4BAAS,SAAS,CAAA,CAAA;AAAA,EAElB,4BAAS,mBAAmB,CAAA;AAAA,CAAA,EA3DxB,gBAAA,CAqDT,SAAA,EAAA,QAAA,EAAA,CAAA,CAAA;AArDS,gBAAA,GAAN,eAAA,CAAA;AAAA,EALN,QAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB,CAAA;AAAA,EACA,YAAA,CAAa,SAAS,CAAC;AAAA,CAAA,EACX,gBAAA,CAAA","file":"AreDirectiveShow.directive.mjs","sourcesContent":["import { A_Caller, A_Inject } from \"@adaas/a-concept\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { AreDirectiveAttribute } from \"@adaas/are-html/attributes/AreDirective.attribute\";\nimport { AreScene, AreStore, AreSyntax } from \"@adaas/are\";\nimport { AreDirective } from \"@adaas/are-html/directive/AreDirective.component\";\nimport { AreDirectiveContext } from \"@adaas/are-html/directive/AreDirective.context\";\nimport { HideElementInstruction } from \"@adaas/are-html/instructions/HideElement.instruction\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n\n/**\n * `$show` directive — conditionally toggles an element's visibility.\n *\n * Unlike `$if`, `$show` keeps the element fully mounted at all times and only\n * flips its inline `display` (Vue `v-show` semantics). The element's subtree,\n * event listeners and scene state are preserved across toggles, which makes it\n * far cheaper than `$if` for things that flip on/off frequently. Use `$if` when\n * the hidden branch is expensive and rarely shown; use `$show` when it toggles\n * often.\n *\n * ⚠️ Known limitations:\n * - Do NOT combine `$show` with `$if`/`$for` on the SAME element — they share\n * an owner node and would fight over its host instruction. Wrap one in a\n * parent element instead.\n * - `$show` forces inline `display:none`, which beats stylesheet rules but will\n * NOT override the element's own inline `:style=\"display:...\"` binding.\n */\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Built-in $show directive. Toggles an element\\'s visibility by flipping its inline display value based on a store expression, keeping the element mounted (subtree, listeners and scene state preserved) instead of unmounting it like $if.'\n})\n@AreDirective.Priority(3)\nexport class AreDirectiveShow extends AreDirective {\n\n\n @AreDirective.Transform\n transform(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(A_Logger) logger: A_Logger,\n ...args: any[]\n ) {\n // $show makes no structural change to the tree — the element stays in\n // place and is only hidden/shown at interpret time. Nothing to do here\n // beyond overriding the base directive's default transform warning.\n logger.debug(`[Transform] directive $SHOW for <${attribute.owner.aseid.toString()}> (no structural change)`)\n }\n\n\n @AreDirective.Compile\n compile(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n @A_Inject(AreSyntax) syntax: AreSyntax,\n\n @A_Inject(AreDirectiveContext) directiveContext?: AreDirectiveContext,\n ...args: any[]\n ): void {\n /**\n * 1. Evaluate the expression to determine the initial visibility.\n */\n const visible = !!syntax.evaluate(attribute.content, store, {\n ...(directiveContext?.scope || {}),\n });\n\n attribute.value = visible;\n\n /**\n * 2. Create a single reusable HideElement mutation parented to the\n * element's host instruction, and cache it on the attribute so\n * update() can plan/unplan the exact same instance.\n */\n const hide = new HideElementInstruction(scene.host!, {});\n attribute.cache = hide;\n\n /**\n * 3. When initially hidden, plan the mutation so the first interpret\n * applies `display:none`. When visible, leave it unplanned.\n */\n if (!visible)\n scene.plan(hide);\n }\n\n\n @AreDirective.Update\n update(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n @A_Inject(AreSyntax) syntax: AreSyntax,\n\n @A_Inject(AreDirectiveContext) directiveContext?: AreDirectiveContext,\n ...args: any[]\n ): void {\n /**\n * 1. Re-evaluate the expression, forwarding the directive context scope\n * (e.g. a `$for` loop variable) so `$show` reacts correctly inside\n * loops.\n */\n const previous = !!attribute.value;\n const next = !!syntax.evaluate(attribute.content, store, {\n ...(directiveContext?.scope || {}),\n });\n\n attribute.value = next;\n\n // Skip when visibility has not changed — avoids redundant DOM writes.\n if (previous === next) return;\n\n const hide = attribute.cache as HideElementInstruction | undefined;\n\n if (!hide) return;\n\n /**\n * 2. Toggle the cached mutation: unplan to reveal, plan to hide. Then\n * re-interpret the owner so the scene diff applies/reverts it.\n */\n if (next)\n scene.unPlan(hide);\n else\n scene.plan(hide);\n\n attribute.owner.interpret();\n }\n\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { A_Scope } from '@adaas/a-concept';
|
|
2
2
|
import { AreEngine, AreSyntax, AreSignalsContext, AreSyntaxTokenMatch } from '@adaas/are';
|
|
3
|
+
import { AreRootCache } from '../lib/AreRoot/AreRootCache.context.mjs';
|
|
3
4
|
|
|
4
5
|
declare class AreHTMLEngine extends AreEngine {
|
|
5
6
|
get DefaultSyntax(): AreSyntax;
|
|
@@ -8,7 +9,7 @@ declare class AreHTMLEngine extends AreEngine {
|
|
|
8
9
|
*
|
|
9
10
|
* @param container
|
|
10
11
|
*/
|
|
11
|
-
init(scope: A_Scope, signalContext?: AreSignalsContext): Promise<void>;
|
|
12
|
+
init(scope: A_Scope, signalContext?: AreSignalsContext, rootCache?: AreRootCache): Promise<void>;
|
|
12
13
|
protected rootElementMatcher(source: string, from: number, to: number, build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch): AreSyntaxTokenMatch | null;
|
|
13
14
|
protected htmlElementMatcher(source: string, from: number, to: number, build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch): AreSyntaxTokenMatch | null;
|
|
14
15
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { A_Scope } from '@adaas/a-concept';
|
|
2
2
|
import { AreEngine, AreSyntax, AreSignalsContext, AreSyntaxTokenMatch } from '@adaas/are';
|
|
3
|
+
import { AreRootCache } from '../lib/AreRoot/AreRootCache.context.js';
|
|
3
4
|
|
|
4
5
|
declare class AreHTMLEngine extends AreEngine {
|
|
5
6
|
get DefaultSyntax(): AreSyntax;
|
|
@@ -8,7 +9,7 @@ declare class AreHTMLEngine extends AreEngine {
|
|
|
8
9
|
*
|
|
9
10
|
* @param container
|
|
10
11
|
*/
|
|
11
|
-
init(scope: A_Scope, signalContext?: AreSignalsContext): Promise<void>;
|
|
12
|
+
init(scope: A_Scope, signalContext?: AreSignalsContext, rootCache?: AreRootCache): Promise<void>;
|
|
12
13
|
protected rootElementMatcher(source: string, from: number, to: number, build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch): AreSyntaxTokenMatch | null;
|
|
13
14
|
protected htmlElementMatcher(source: string, from: number, to: number, build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch): AreSyntaxTokenMatch | null;
|
|
14
15
|
/**
|
|
@@ -16,6 +16,7 @@ var lifecycle = require('@adaas/are-html/lifecycle');
|
|
|
16
16
|
var transformer = require('@adaas/are-html/transformer');
|
|
17
17
|
var AreHTML_compiler = require('./AreHTML.compiler');
|
|
18
18
|
var AreHTML_constants = require('./AreHTML.constants');
|
|
19
|
+
var AreRootCache_context = require('../lib/AreRoot/AreRootCache.context');
|
|
19
20
|
|
|
20
21
|
var __defProp = Object.defineProperty;
|
|
21
22
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -72,7 +73,7 @@ exports.AreHTMLEngine = class AreHTMLEngine extends are.AreEngine {
|
|
|
72
73
|
]
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
|
-
async init(scope, signalContext) {
|
|
76
|
+
async init(scope, signalContext, rootCache) {
|
|
76
77
|
this.package(scope, {
|
|
77
78
|
context: new AreHTML_context.AreHTMLEngineContext({}),
|
|
78
79
|
syntax: this.DefaultSyntax,
|
|
@@ -86,6 +87,10 @@ exports.AreHTMLEngine = class AreHTMLEngine extends are.AreEngine {
|
|
|
86
87
|
signalContext = new are.AreSignalsContext();
|
|
87
88
|
scope.register(signalContext);
|
|
88
89
|
}
|
|
90
|
+
if (!rootCache) {
|
|
91
|
+
rootCache = new AreRootCache_context.AreRootCache();
|
|
92
|
+
scope.register(rootCache);
|
|
93
|
+
}
|
|
89
94
|
}
|
|
90
95
|
rootElementMatcher(source, from, to, build) {
|
|
91
96
|
const rootTag = "are-root";
|
|
@@ -195,7 +200,8 @@ __decorateClass([
|
|
|
195
200
|
before: /.*/
|
|
196
201
|
}),
|
|
197
202
|
__decorateParam(0, aConcept.A_Inject(aConcept.A_Scope)),
|
|
198
|
-
__decorateParam(1, aConcept.A_Inject(are.AreSignalsContext))
|
|
203
|
+
__decorateParam(1, aConcept.A_Inject(are.AreSignalsContext)),
|
|
204
|
+
__decorateParam(2, aConcept.A_Inject(AreRootCache_context.AreRootCache))
|
|
199
205
|
], exports.AreHTMLEngine.prototype, "init", 1);
|
|
200
206
|
exports.AreHTMLEngine = __decorateClass([
|
|
201
207
|
core.A_Frame.Define({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/engine/AreHTML.engine.ts"],"names":["AreHTMLEngine","AreEngine","AreSyntax","AreComment","AreInterpolation","AreRootNode","AreComponentNode","AreText","AreHTMLEngineContext","AreHTMLCompiler","AreHTMLInterpreter","AreHTMLTokenizer","AreHTMLLifecycle","AreHTMLTransformer","AreSignalsContext","content","match","isVoidElement","A_Feature","A_ServiceFeatures","A_Scope","A_Frame"],"mappings":"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","file":"AreHTML.engine.js","sourcesContent":["import { A_Feature, A_Inject, A_Scope } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\"\nimport { A_ServiceFeatures } from \"@adaas/a-utils/a-service\";\nimport { AreEngine, AreSyntaxTokenMatch, AreSyntax, AreSignalsContext } from \"@adaas/are\";\nimport { AreHTMLInterpreter } from \"@adaas/are-html/interpreter\";\nimport { AreHTMLEngineContext } from \"./AreHTML.context\";\nimport { AreInterpolation } from \"@adaas/are-html/nodes/AreInterpolation\";\nimport { AreText } from \"@adaas/are-html/nodes/AreText\";\nimport { AreComment } from \"@adaas/are-html/nodes/AreComment\";\nimport { AreComponentNode } from \"@adaas/are-html/nodes/AreComponent\";\nimport { AreHTMLTokenizer } from \"@adaas/are-html/tokenizer\";\nimport { AreRootNode } from \"@adaas/are-html/nodes/AreRoot\";\nimport { AreHTMLLifecycle } from \"@adaas/are-html/lifecycle\";\nimport { AreHTMLTransformer } from \"@adaas/are-html/transformer\";\nimport { AreHTMLCompiler } from \"./AreHTML.compiler\";\nimport { isVoidElement } from \"./AreHTML.constants\";\n\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Concrete HTML rendering engine that assembles the full ARE pipeline for web environments. Bootstraps and wires AreHTMLTokenizer, AreHTMLTransformer, AreHTMLCompiler, AreHTMLInterpreter, and AreHTMLLifecycle; mounts root nodes from inline or fetched templates; and drives reactive re-renders via the AreSignals bus.'\n})\nexport class AreHTMLEngine extends AreEngine {\n\n\n\n get DefaultSyntax() {\n return new AreSyntax({\n trimWhitespace: true,\n strictMode: true,\n rules: [\n // HTML comments\n {\n opening: '<!--',\n closing: '-->',\n component: AreComment,\n priority: 10,\n nested: false,\n extract: (raw) => ({ content: raw.slice(4, -3).trim() }),\n },\n // interpolations\n {\n opening: '{{',\n closing: '}}',\n component: AreInterpolation,\n priority: 9,\n nested: false,\n extract: (_, match) => ({ key: match.content }),\n },\n // are-root — matched before generic elements, produces AreRootNode\n {\n matcher: this.rootElementMatcher.bind(this),\n component: AreRootNode,\n priority: 5,\n },\n // generic HTML elements\n {\n matcher: this.htmlElementMatcher.bind(this),\n component: AreComponentNode,\n priority: 4,\n },\n // plain text fallback\n {\n component: AreText,\n priority: 0,\n },\n ],\n })\n }\n\n\n /**\n * Inject AreHTMLSyntax into the container scope before loading\n * \n * @param container \n */\n @A_Feature.Extend({\n name: A_ServiceFeatures.onBeforeLoad,\n before: /.*/\n })\n async init(\n @A_Inject(A_Scope) scope: A_Scope,\n @A_Inject(AreSignalsContext) signalContext?: AreSignalsContext\n ) {\n this.package(scope, {\n context: new AreHTMLEngineContext({}),\n syntax: this.DefaultSyntax,\n compiler: AreHTMLCompiler,\n interpreter: AreHTMLInterpreter,\n tokenizer: AreHTMLTokenizer,\n lifecycle: AreHTMLLifecycle,\n transformer: AreHTMLTransformer,\n });\n\n if(!signalContext) {\n signalContext = new AreSignalsContext();\n scope.register(signalContext);\n }\n }\n\n\n protected rootElementMatcher(\n source: string,\n from: number,\n to: number,\n build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch\n ): AreSyntaxTokenMatch | null {\n\n // const rootTag = this.config.rootTag\n const rootTag = 'are-root';\n\n const tagStart = source.indexOf('<', from)\n if (tagStart === -1 || tagStart >= to) return null\n\n // only match if the tag name is exactly the configured root tag\n const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/)\n if (!tagNameMatch || tagNameMatch[1].toLowerCase() !== rootTag) return null\n\n // delegate the actual matching to the shared HTML element logic\n return this.htmlElementMatcher(source, from, to, build)\n }\n\n protected htmlElementMatcher(\n source: string,\n from: number,\n to: number,\n build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch\n ): AreSyntaxTokenMatch | null {\n let index = from\n\n while (index < to) {\n const tagStart = source.indexOf('<', index)\n if (tagStart === -1 || tagStart >= to) return null\n\n // skip comments, closing tags, doctype, processing instructions\n if (source.startsWith('<!--', tagStart)) { index = tagStart + 1; continue }\n if (source[tagStart + 1] === '/') { index = tagStart + 1; continue }\n if (source[tagStart + 1] === '!' || source[tagStart + 1] === '?') { index = tagStart + 1; continue }\n\n const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/)\n if (!tagNameMatch) { index = tagStart + 1; continue }\n\n const tagName = tagNameMatch[1]\n const openingTagEnd = AreHTMLEngine.findTagClose(source, tagStart)\n if (openingTagEnd === -1) return null\n\n // extract id attribute if present in the opening tag\n const openingTagStr = source.slice(tagStart, openingTagEnd + 1)\n const idMatch = openingTagStr.match(/\\bid=[\"']([^\"']*)[\"']/)\n const id = idMatch ? idMatch[1] : undefined\n\n // self-closing: <br/> or <input/>\n if (source[openingTagEnd - 1] === '/') {\n const raw = source.slice(tagStart, openingTagEnd + 1)\n const content = source.slice(tagStart + tagNameMatch[0].length, openingTagEnd - 1)\n const match = build(raw, content, tagStart, '/>')\n match.payload = { entity: tagName, selfClose: true, id }\n return match\n }\n\n // HTML5 void elements: <input>, <br>, <img>, etc. — treat as self-closing\n if (isVoidElement(tagName)) {\n const raw = source.slice(tagStart, openingTagEnd + 1)\n const content = source.slice(tagStart + tagNameMatch[0].length, openingTagEnd)\n const match = build(raw, content, tagStart, '>')\n match.payload = { entity: tagName, selfClose: true, id }\n return match\n }\n\n // find matching closing tag respecting nesting\n const closingTag = `</${tagName}>`\n let level = 0\n let searchIndex = openingTagEnd + 1\n let closingStart = -1\n\n while (searchIndex < to) {\n const nextOpen = source.indexOf(`<${tagName}`, searchIndex)\n const nextClose = source.indexOf(closingTag, searchIndex)\n if (nextClose === -1) break\n\n if (nextOpen !== -1 && nextOpen < nextClose) {\n const charAfter = source[nextOpen + tagName.length + 1]\n if (charAfter === ' ' || charAfter === '>' || charAfter === '/') {\n // Skip self-closing nested occurrences, e.g. <div/> inside <div>...</div>.\n const innerEnd = AreHTMLEngine.findTagClose(source, nextOpen)\n const isSelfClose = innerEnd !== -1 && source[innerEnd - 1] === '/'\n\n if (!isSelfClose) {\n level++\n }\n searchIndex = (innerEnd === -1 ? nextOpen + tagName.length + 1 : innerEnd + 1)\n continue\n }\n }\n\n if (level === 0) { closingStart = nextClose; break }\n level--\n searchIndex = nextClose + closingTag.length\n }\n\n if (closingStart === -1) return null\n\n const fullTag = source.slice(tagStart, closingStart + closingTag.length)\n const content = source.slice(openingTagEnd + 1, closingStart)\n const match = build(fullTag, content, tagStart, closingTag)\n match.payload = { entity: tagName, selfClose: false, id }\n return match\n }\n return null\n }\n\n /**\n * Find the index of the closing `>` of an opening tag, skipping over\n * `>` characters that appear inside quoted attribute values.\n */\n private static findTagClose(source: string, from: number): number {\n let inSingle = false\n let inDouble = false\n\n for (let i = from; i < source.length; i++) {\n const ch = source[i]\n if (ch === '\"' && !inSingle) inDouble = !inDouble\n else if (ch === \"'\" && !inDouble) inSingle = !inSingle\n else if (ch === '>' && !inSingle && !inDouble) return i\n }\n\n return -1\n }\n\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/engine/AreHTML.engine.ts"],"names":["AreHTMLEngine","AreEngine","AreSyntax","AreComment","AreInterpolation","AreRootNode","AreComponentNode","AreText","AreHTMLEngineContext","AreHTMLCompiler","AreHTMLInterpreter","AreHTMLTokenizer","AreHTMLLifecycle","AreHTMLTransformer","AreSignalsContext","AreRootCache","content","match","isVoidElement","A_Feature","A_ServiceFeatures","A_Scope","A_Frame"],"mappings":"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","file":"AreHTML.engine.js","sourcesContent":["import { A_Feature, A_Inject, A_Scope } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\"\nimport { A_ServiceFeatures } from \"@adaas/a-utils/a-service\";\nimport { AreEngine, AreSyntaxTokenMatch, AreSyntax, AreSignalsContext } from \"@adaas/are\";\nimport { AreHTMLInterpreter } from \"@adaas/are-html/interpreter\";\nimport { AreHTMLEngineContext } from \"./AreHTML.context\";\nimport { AreInterpolation } from \"@adaas/are-html/nodes/AreInterpolation\";\nimport { AreText } from \"@adaas/are-html/nodes/AreText\";\nimport { AreComment } from \"@adaas/are-html/nodes/AreComment\";\nimport { AreComponentNode } from \"@adaas/are-html/nodes/AreComponent\";\nimport { AreHTMLTokenizer } from \"@adaas/are-html/tokenizer\";\nimport { AreRootNode } from \"@adaas/are-html/nodes/AreRoot\";\nimport { AreHTMLLifecycle } from \"@adaas/are-html/lifecycle\";\nimport { AreHTMLTransformer } from \"@adaas/are-html/transformer\";\nimport { AreHTMLCompiler } from \"./AreHTML.compiler\";\nimport { isVoidElement } from \"./AreHTML.constants\";\nimport { AreRootCache } from \"../lib/AreRoot/AreRootCache.context\";\n\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Concrete HTML rendering engine that assembles the full ARE pipeline for web environments. Bootstraps and wires AreHTMLTokenizer, AreHTMLTransformer, AreHTMLCompiler, AreHTMLInterpreter, and AreHTMLLifecycle; mounts root nodes from inline or fetched templates; and drives reactive re-renders via the AreSignals bus.'\n})\nexport class AreHTMLEngine extends AreEngine {\n\n\n\n get DefaultSyntax() {\n return new AreSyntax({\n trimWhitespace: true,\n strictMode: true,\n rules: [\n // HTML comments\n {\n opening: '<!--',\n closing: '-->',\n component: AreComment,\n priority: 10,\n nested: false,\n extract: (raw) => ({ content: raw.slice(4, -3).trim() }),\n },\n // interpolations\n {\n opening: '{{',\n closing: '}}',\n component: AreInterpolation,\n priority: 9,\n nested: false,\n extract: (_, match) => ({ key: match.content }),\n },\n // are-root — matched before generic elements, produces AreRootNode\n {\n matcher: this.rootElementMatcher.bind(this),\n component: AreRootNode,\n priority: 5,\n },\n // generic HTML elements\n {\n matcher: this.htmlElementMatcher.bind(this),\n component: AreComponentNode,\n priority: 4,\n },\n // plain text fallback\n {\n component: AreText,\n priority: 0,\n },\n ],\n })\n }\n\n\n /**\n * Inject AreHTMLSyntax into the container scope before loading\n * \n * @param container \n */\n @A_Feature.Extend({\n name: A_ServiceFeatures.onBeforeLoad,\n before: /.*/\n })\n async init(\n @A_Inject(A_Scope) scope: A_Scope,\n @A_Inject(AreSignalsContext) signalContext?: AreSignalsContext,\n @A_Inject(AreRootCache) rootCache?: AreRootCache\n ) {\n this.package(scope, {\n context: new AreHTMLEngineContext({}),\n syntax: this.DefaultSyntax,\n compiler: AreHTMLCompiler,\n interpreter: AreHTMLInterpreter,\n tokenizer: AreHTMLTokenizer,\n lifecycle: AreHTMLLifecycle,\n transformer: AreHTMLTransformer,\n });\n\n if(!signalContext) {\n signalContext = new AreSignalsContext();\n scope.register(signalContext);\n }\n\n // Default per-root subtree cache used by AreRoot for fast route-back\n // re-injection. Apps may register their own (e.g. with a custom limit)\n // before load to override this.\n if (!rootCache) {\n rootCache = new AreRootCache();\n scope.register(rootCache);\n }\n }\n\n\n protected rootElementMatcher(\n source: string,\n from: number,\n to: number,\n build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch\n ): AreSyntaxTokenMatch | null {\n\n // const rootTag = this.config.rootTag\n const rootTag = 'are-root';\n\n const tagStart = source.indexOf('<', from)\n if (tagStart === -1 || tagStart >= to) return null\n\n // only match if the tag name is exactly the configured root tag\n const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/)\n if (!tagNameMatch || tagNameMatch[1].toLowerCase() !== rootTag) return null\n\n // delegate the actual matching to the shared HTML element logic\n return this.htmlElementMatcher(source, from, to, build)\n }\n\n protected htmlElementMatcher(\n source: string,\n from: number,\n to: number,\n build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch\n ): AreSyntaxTokenMatch | null {\n let index = from\n\n while (index < to) {\n const tagStart = source.indexOf('<', index)\n if (tagStart === -1 || tagStart >= to) return null\n\n // skip comments, closing tags, doctype, processing instructions\n if (source.startsWith('<!--', tagStart)) { index = tagStart + 1; continue }\n if (source[tagStart + 1] === '/') { index = tagStart + 1; continue }\n if (source[tagStart + 1] === '!' || source[tagStart + 1] === '?') { index = tagStart + 1; continue }\n\n const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/)\n if (!tagNameMatch) { index = tagStart + 1; continue }\n\n const tagName = tagNameMatch[1]\n const openingTagEnd = AreHTMLEngine.findTagClose(source, tagStart)\n if (openingTagEnd === -1) return null\n\n // extract id attribute if present in the opening tag\n const openingTagStr = source.slice(tagStart, openingTagEnd + 1)\n const idMatch = openingTagStr.match(/\\bid=[\"']([^\"']*)[\"']/)\n const id = idMatch ? idMatch[1] : undefined\n\n // self-closing: <br/> or <input/>\n if (source[openingTagEnd - 1] === '/') {\n const raw = source.slice(tagStart, openingTagEnd + 1)\n const content = source.slice(tagStart + tagNameMatch[0].length, openingTagEnd - 1)\n const match = build(raw, content, tagStart, '/>')\n match.payload = { entity: tagName, selfClose: true, id }\n return match\n }\n\n // HTML5 void elements: <input>, <br>, <img>, etc. — treat as self-closing\n if (isVoidElement(tagName)) {\n const raw = source.slice(tagStart, openingTagEnd + 1)\n const content = source.slice(tagStart + tagNameMatch[0].length, openingTagEnd)\n const match = build(raw, content, tagStart, '>')\n match.payload = { entity: tagName, selfClose: true, id }\n return match\n }\n\n // find matching closing tag respecting nesting\n const closingTag = `</${tagName}>`\n let level = 0\n let searchIndex = openingTagEnd + 1\n let closingStart = -1\n\n while (searchIndex < to) {\n const nextOpen = source.indexOf(`<${tagName}`, searchIndex)\n const nextClose = source.indexOf(closingTag, searchIndex)\n if (nextClose === -1) break\n\n if (nextOpen !== -1 && nextOpen < nextClose) {\n const charAfter = source[nextOpen + tagName.length + 1]\n if (charAfter === ' ' || charAfter === '>' || charAfter === '/') {\n // Skip self-closing nested occurrences, e.g. <div/> inside <div>...</div>.\n const innerEnd = AreHTMLEngine.findTagClose(source, nextOpen)\n const isSelfClose = innerEnd !== -1 && source[innerEnd - 1] === '/'\n\n if (!isSelfClose) {\n level++\n }\n searchIndex = (innerEnd === -1 ? nextOpen + tagName.length + 1 : innerEnd + 1)\n continue\n }\n }\n\n if (level === 0) { closingStart = nextClose; break }\n level--\n searchIndex = nextClose + closingTag.length\n }\n\n if (closingStart === -1) return null\n\n const fullTag = source.slice(tagStart, closingStart + closingTag.length)\n const content = source.slice(openingTagEnd + 1, closingStart)\n const match = build(fullTag, content, tagStart, closingTag)\n match.payload = { entity: tagName, selfClose: false, id }\n return match\n }\n return null\n }\n\n /**\n * Find the index of the closing `>` of an opening tag, skipping over\n * `>` characters that appear inside quoted attribute values.\n */\n private static findTagClose(source: string, from: number): number {\n let inSingle = false\n let inDouble = false\n\n for (let i = from; i < source.length; i++) {\n const ch = source[i]\n if (ch === '\"' && !inSingle) inDouble = !inDouble\n else if (ch === \"'\" && !inDouble) inSingle = !inSingle\n else if (ch === '>' && !inSingle && !inDouble) return i\n }\n\n return -1\n }\n\n}"]}
|
|
@@ -15,6 +15,7 @@ import { AreHTMLLifecycle } from '@adaas/are-html/lifecycle';
|
|
|
15
15
|
import { AreHTMLTransformer } from '@adaas/are-html/transformer';
|
|
16
16
|
import { AreHTMLCompiler } from './AreHTML.compiler';
|
|
17
17
|
import { isVoidElement } from './AreHTML.constants';
|
|
18
|
+
import { AreRootCache } from '../lib/AreRoot/AreRootCache.context';
|
|
18
19
|
|
|
19
20
|
let AreHTMLEngine = class extends AreEngine {
|
|
20
21
|
get DefaultSyntax() {
|
|
@@ -60,7 +61,7 @@ let AreHTMLEngine = class extends AreEngine {
|
|
|
60
61
|
]
|
|
61
62
|
});
|
|
62
63
|
}
|
|
63
|
-
async init(scope, signalContext) {
|
|
64
|
+
async init(scope, signalContext, rootCache) {
|
|
64
65
|
this.package(scope, {
|
|
65
66
|
context: new AreHTMLEngineContext({}),
|
|
66
67
|
syntax: this.DefaultSyntax,
|
|
@@ -74,6 +75,10 @@ let AreHTMLEngine = class extends AreEngine {
|
|
|
74
75
|
signalContext = new AreSignalsContext();
|
|
75
76
|
scope.register(signalContext);
|
|
76
77
|
}
|
|
78
|
+
if (!rootCache) {
|
|
79
|
+
rootCache = new AreRootCache();
|
|
80
|
+
scope.register(rootCache);
|
|
81
|
+
}
|
|
77
82
|
}
|
|
78
83
|
rootElementMatcher(source, from, to, build) {
|
|
79
84
|
const rootTag = "are-root";
|
|
@@ -183,7 +188,8 @@ __decorateClass([
|
|
|
183
188
|
before: /.*/
|
|
184
189
|
}),
|
|
185
190
|
__decorateParam(0, A_Inject(A_Scope)),
|
|
186
|
-
__decorateParam(1, A_Inject(AreSignalsContext))
|
|
191
|
+
__decorateParam(1, A_Inject(AreSignalsContext)),
|
|
192
|
+
__decorateParam(2, A_Inject(AreRootCache))
|
|
187
193
|
], AreHTMLEngine.prototype, "init", 1);
|
|
188
194
|
AreHTMLEngine = __decorateClass([
|
|
189
195
|
A_Frame.Define({
|