@nisli/core 0.56.0 → 0.57.1
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 +70 -9
- package/dist/bundler/component.js +409 -0
- package/dist/bundler/component.js.map +7 -0
- package/dist/bundler/context.js +27 -0
- package/dist/bundler/context.js.map +7 -0
- package/dist/bundler/diagnostics.js +55 -0
- package/dist/bundler/diagnostics.js.map +7 -0
- package/dist/bundler/disposable.js +9 -0
- package/dist/bundler/disposable.js.map +7 -0
- package/dist/bundler/element-context.js +47 -0
- package/dist/bundler/element-context.js.map +7 -0
- package/dist/bundler/emitter.js +70 -0
- package/dist/bundler/emitter.js.map +7 -0
- package/dist/bundler/hmr/registry.js +72 -0
- package/dist/bundler/hmr/registry.js.map +7 -0
- package/dist/bundler/hmr/transform.js +30 -0
- package/dist/bundler/hmr/transform.js.map +7 -0
- package/dist/bundler/index.js +103 -0
- package/dist/bundler/index.js.map +7 -0
- package/dist/bundler/injector.js +75 -0
- package/dist/bundler/injector.js.map +7 -0
- package/dist/bundler/lifecycle.js +56 -0
- package/dist/bundler/lifecycle.js.map +7 -0
- package/dist/bundler/projection.js +92 -0
- package/dist/bundler/projection.js.map +7 -0
- package/dist/bundler/query.js +302 -0
- package/dist/bundler/query.js.map +7 -0
- package/dist/bundler/ref.js +16 -0
- package/dist/bundler/ref.js.map +7 -0
- package/dist/bundler/resource.js +99 -0
- package/dist/bundler/resource.js.map +7 -0
- package/dist/bundler/settle.js +43 -0
- package/dist/bundler/settle.js.map +7 -0
- package/dist/bundler/signal.js +403 -0
- package/dist/bundler/signal.js.map +7 -0
- package/dist/bundler/template-audit.js +162 -0
- package/dist/bundler/template-audit.js.map +7 -0
- package/dist/bundler/template.js +922 -0
- package/dist/bundler/template.js.map +7 -0
- package/dist/bundler/view-transition.js +20 -0
- package/dist/bundler/view-transition.js.map +7 -0
- package/dist/bundler/vite-hmr/plugin.js +32 -0
- package/dist/bundler/vite-hmr/plugin.js.map +7 -0
- package/dist/bundler/vite-hmr/runtime.js +8 -0
- package/dist/bundler/vite-hmr/runtime.js.map +7 -0
- package/dist/index.js +2682 -47
- package/dist/index.js.map +7 -1
- package/dist/index.production.js +2 -0
- package/dist/index.production.js.map +6 -0
- package/dist/{diagnostics.d.ts → types/diagnostics.d.ts} +8 -15
- package/dist/{template-audit.d.ts → types/template-audit.d.ts} +4 -5
- package/dist/{template.d.ts → types/template.d.ts} +2 -1
- package/package.json +15 -10
- package/dist/component.js +0 -633
- package/dist/component.js.map +0 -1
- package/dist/context.js +0 -55
- package/dist/context.js.map +0 -1
- package/dist/diagnostics.js +0 -118
- package/dist/diagnostics.js.map +0 -1
- package/dist/disposable.js +0 -8
- package/dist/disposable.js.map +0 -1
- package/dist/element-context.js +0 -108
- package/dist/element-context.js.map +0 -1
- package/dist/emitter.js +0 -91
- package/dist/emitter.js.map +0 -1
- package/dist/hmr/registry.js +0 -136
- package/dist/hmr/registry.js.map +0 -1
- package/dist/hmr/transform.js +0 -52
- package/dist/hmr/transform.js.map +0 -1
- package/dist/injector.js +0 -118
- package/dist/injector.js.map +0 -1
- package/dist/lifecycle.js +0 -117
- package/dist/lifecycle.js.map +0 -1
- package/dist/projection.js +0 -179
- package/dist/projection.js.map +0 -1
- package/dist/query.js +0 -429
- package/dist/query.js.map +0 -1
- package/dist/ref.js +0 -43
- package/dist/ref.js.map +0 -1
- package/dist/resource.js +0 -129
- package/dist/resource.js.map +0 -1
- package/dist/settle.js +0 -106
- package/dist/settle.js.map +0 -1
- package/dist/signal.js +0 -645
- package/dist/signal.js.map +0 -1
- package/dist/template-audit.js +0 -246
- package/dist/template-audit.js.map +0 -1
- package/dist/template.js +0 -1244
- package/dist/template.js.map +0 -1
- package/dist/view-transition.js +0 -98
- package/dist/view-transition.js.map +0 -1
- package/dist/vite-hmr/plugin.js +0 -62
- package/dist/vite-hmr/plugin.js.map +0 -1
- package/dist/vite-hmr/runtime.js +0 -17
- package/dist/vite-hmr/runtime.js.map +0 -1
- /package/dist/{component.d.ts → types/component.d.ts} +0 -0
- /package/dist/{context.d.ts → types/context.d.ts} +0 -0
- /package/dist/{disposable.d.ts → types/disposable.d.ts} +0 -0
- /package/dist/{element-context.d.ts → types/element-context.d.ts} +0 -0
- /package/dist/{emitter.d.ts → types/emitter.d.ts} +0 -0
- /package/dist/{hmr → types/hmr}/registry.d.ts +0 -0
- /package/dist/{hmr → types/hmr}/transform.d.ts +0 -0
- /package/dist/{index.d.ts → types/index.d.ts} +0 -0
- /package/dist/{injector.d.ts → types/injector.d.ts} +0 -0
- /package/dist/{lifecycle.d.ts → types/lifecycle.d.ts} +0 -0
- /package/dist/{projection.d.ts → types/projection.d.ts} +0 -0
- /package/dist/{query.d.ts → types/query.d.ts} +0 -0
- /package/dist/{ref.d.ts → types/ref.d.ts} +0 -0
- /package/dist/{resource.d.ts → types/resource.d.ts} +0 -0
- /package/dist/{settle.d.ts → types/settle.d.ts} +0 -0
- /package/dist/{signal.d.ts → types/signal.d.ts} +0 -0
- /package/dist/{view-transition.d.ts → types/view-transition.d.ts} +0 -0
- /package/dist/{vite-hmr → types/vite-hmr}/plugin.d.ts +0 -0
- /package/dist/{vite-hmr → types/vite-hmr}/runtime.d.ts +0 -0
package/dist/injector.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* injector.ts — Dependency injection: inject(), provide(), class-as-token
|
|
3
|
-
*
|
|
4
|
-
* Two key insights from Angular's evolution:
|
|
5
|
-
* 1. The class IS the token — no createToken() needed for 99% of cases
|
|
6
|
-
* 2. provide() is optional — inject() auto-creates singletons on first call
|
|
7
|
-
*
|
|
8
|
-
* ```ts
|
|
9
|
-
* class BacklogAPI {
|
|
10
|
-
* async getTasks(): Promise<Task[]> { ... }
|
|
11
|
-
* }
|
|
12
|
-
*
|
|
13
|
-
* // In component setup:
|
|
14
|
-
* const api = inject(BacklogAPI); // auto-created singleton
|
|
15
|
-
*
|
|
16
|
-
* // In tests:
|
|
17
|
-
* provide(BacklogAPI, () => new MockAPI());
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
import { hasContext, getCurrentComponent } from './context.js';
|
|
21
|
-
import { formatDiag, isDev } from './diagnostics.js';
|
|
22
|
-
// ── Global singleton registry ───────────────────────────────────────
|
|
23
|
-
/** Stores singleton instances keyed by constructor or token. */
|
|
24
|
-
const singletonCache = new Map();
|
|
25
|
-
/** Stores factory overrides from provide(). */
|
|
26
|
-
const factoryOverrides = new Map();
|
|
27
|
-
/** Tracks which constructors are currently being instantiated (circular detection). */
|
|
28
|
-
const instantiating = new Set();
|
|
29
|
-
export function inject(token) {
|
|
30
|
-
// Check cache first
|
|
31
|
-
if (singletonCache.has(token)) {
|
|
32
|
-
return singletonCache.get(token);
|
|
33
|
-
}
|
|
34
|
-
// Circular dependency detection
|
|
35
|
-
if (instantiating.has(token)) {
|
|
36
|
-
const name = typeof token === 'function' ? token.name : token.name;
|
|
37
|
-
throw new Error(`Circular dependency detected when instantiating '${name}'. ` +
|
|
38
|
-
'Check your service constructors for circular inject() calls.');
|
|
39
|
-
}
|
|
40
|
-
instantiating.add(token);
|
|
41
|
-
try {
|
|
42
|
-
let instance;
|
|
43
|
-
// Check for factory override
|
|
44
|
-
const factory = factoryOverrides.get(token);
|
|
45
|
-
if (factory) {
|
|
46
|
-
instance = factory();
|
|
47
|
-
}
|
|
48
|
-
else if (typeof token === 'function') {
|
|
49
|
-
// Class token — auto-create via constructor
|
|
50
|
-
instance = new token();
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
// InjectionToken with default factory
|
|
54
|
-
const injToken = token;
|
|
55
|
-
if (injToken._factory) {
|
|
56
|
-
instance = injToken._factory();
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
throw new Error(`No provider found for token '${injToken.name}'. ` +
|
|
60
|
-
'Use provide() to register a factory before calling inject().');
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
singletonCache.set(token, instance);
|
|
64
|
-
return instance;
|
|
65
|
-
}
|
|
66
|
-
finally {
|
|
67
|
-
instantiating.delete(token);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
export function provide(token, factory) {
|
|
71
|
-
if (isDev() && singletonCache.has(token)) {
|
|
72
|
-
const name = typeof token === 'function' ? token.name : token.name;
|
|
73
|
-
throw new Error(formatDiag('N501', `provide(${name}) after '${name}' was already instantiated — existing `
|
|
74
|
-
+ `consumers keep the old instance while new inject() calls would get the `
|
|
75
|
-
+ `new one (mixed-instance split). Call resetInjector() first (tests), or `
|
|
76
|
-
+ `provide() before the first inject().`));
|
|
77
|
-
}
|
|
78
|
-
factoryOverrides.set(token, factory);
|
|
79
|
-
// Remove cached instance so next inject() uses the new factory
|
|
80
|
-
singletonCache.delete(token);
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Create an injection token for non-class dependencies.
|
|
84
|
-
* Use this for config objects, primitives, or interfaces.
|
|
85
|
-
*
|
|
86
|
-
* ```ts
|
|
87
|
-
* const AppConfig = createToken<{ apiUrl: string }>('AppConfig');
|
|
88
|
-
* provide(AppConfig, () => ({ apiUrl: '/api' }));
|
|
89
|
-
* const config = inject(AppConfig);
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
|
-
export function createToken(name, defaultFactory) {
|
|
93
|
-
return {
|
|
94
|
-
__brand: 'InjectionToken',
|
|
95
|
-
name,
|
|
96
|
-
_factory: defaultFactory,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
// Hooks run by resetInjector() — module-level caches elsewhere (settle's
|
|
100
|
-
// pending registry) stay test-isolated without upside-down imports: those
|
|
101
|
-
// modules import the injector and self-register, never the reverse.
|
|
102
|
-
const resetHooks = new Set();
|
|
103
|
-
/** @internal Register a hook run by every resetInjector() call. */
|
|
104
|
-
export function registerResetHook(hook) {
|
|
105
|
-
resetHooks.add(hook);
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Reset the injector — clears all singletons and factory overrides.
|
|
109
|
-
* Used in tests to ensure isolation between test cases.
|
|
110
|
-
*/
|
|
111
|
-
export function resetInjector() {
|
|
112
|
-
singletonCache.clear();
|
|
113
|
-
factoryOverrides.clear();
|
|
114
|
-
instantiating.clear();
|
|
115
|
-
for (const hook of resetHooks)
|
|
116
|
-
hook();
|
|
117
|
-
}
|
|
118
|
-
//# sourceMappingURL=injector.js.map
|
package/dist/injector.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"injector.js","sourceRoot":"","sources":["../src/injector.ts"],"names":[],"mappings":"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"}
|
package/dist/lifecycle.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lifecycle.ts — Post-mount and cleanup lifecycle hooks
|
|
3
|
-
*
|
|
4
|
-
* `onMount()` registers a callback that runs after the component's
|
|
5
|
-
* template is mounted to the DOM. If the callback returns a function,
|
|
6
|
-
* that function runs on disconnect (cleanup).
|
|
7
|
-
*
|
|
8
|
-
* `onCleanup()` registers a standalone cleanup callback that runs
|
|
9
|
-
* on disconnect — for cases where you need cleanup without mount logic.
|
|
10
|
-
*
|
|
11
|
-
* Both must be called synchronously during component setup.
|
|
12
|
-
*
|
|
13
|
-
* ```ts
|
|
14
|
-
* component('my-el', (props, host) => {
|
|
15
|
-
* onMount(() => {
|
|
16
|
-
* host.querySelector('input')?.focus();
|
|
17
|
-
* return () => console.log('unmounted');
|
|
18
|
-
* });
|
|
19
|
-
*
|
|
20
|
-
* onCleanup(() => clearInterval(timerId));
|
|
21
|
-
*
|
|
22
|
-
* return html`<input />`;
|
|
23
|
-
* });
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
import { hasContext, getCurrentComponent } from './context.js';
|
|
27
|
-
// ── Mount callback storage ──────────────────────────────────────────
|
|
28
|
-
/** Mount callbacks are stored on the component host and called after template mount. */
|
|
29
|
-
const mountCallbacks = new WeakMap();
|
|
30
|
-
/**
|
|
31
|
-
* Register a callback to run after the component's template is mounted.
|
|
32
|
-
* If the callback returns a function, it will be called on disconnect.
|
|
33
|
-
*
|
|
34
|
-
* Must be called synchronously during component setup.
|
|
35
|
-
*/
|
|
36
|
-
export function onMount(callback) {
|
|
37
|
-
if (!hasContext()) {
|
|
38
|
-
throw new Error('onMount() called outside setup(). ' +
|
|
39
|
-
'It can only be called during component initialization.');
|
|
40
|
-
}
|
|
41
|
-
const comp = getCurrentComponent();
|
|
42
|
-
let callbacks = mountCallbacks.get(comp);
|
|
43
|
-
if (!callbacks) {
|
|
44
|
-
callbacks = [];
|
|
45
|
-
mountCallbacks.set(comp, callbacks);
|
|
46
|
-
}
|
|
47
|
-
callbacks.push(callback);
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Register a cleanup callback to run on disconnect.
|
|
51
|
-
* This is a convenience for cases where you need cleanup without mount logic.
|
|
52
|
-
*
|
|
53
|
-
* Must be called synchronously during component setup.
|
|
54
|
-
*/
|
|
55
|
-
export function onCleanup(callback) {
|
|
56
|
-
if (!hasContext()) {
|
|
57
|
-
throw new Error('onCleanup() called outside setup(). ' +
|
|
58
|
-
'It can only be called during component initialization.');
|
|
59
|
-
}
|
|
60
|
-
getCurrentComponent().addDisposer(callback);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Listen for a DOM event on a target and auto-dispose the listener when the
|
|
64
|
-
* component disconnects. Works with any EventTarget (host element, document,
|
|
65
|
-
* window, etc.). Must be called during component setup.
|
|
66
|
-
*
|
|
67
|
-
* ```ts
|
|
68
|
-
* useHostEvent(host, 'click', (e) => {
|
|
69
|
-
* // Runs on each click
|
|
70
|
-
* });
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
export function useHostEvent(target, eventName, handler) {
|
|
74
|
-
if (!hasContext()) {
|
|
75
|
-
throw new Error('useHostEvent() called outside setup(). ' +
|
|
76
|
-
'It can only be called during component initialization.');
|
|
77
|
-
}
|
|
78
|
-
target.addEventListener(eventName, handler);
|
|
79
|
-
getCurrentComponent().addDisposer(() => {
|
|
80
|
-
target.removeEventListener(eventName, handler);
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Run all registered mount callbacks for a component host.
|
|
85
|
-
* Called by component.ts after the template is mounted to the DOM.
|
|
86
|
-
*
|
|
87
|
-
* A throw here PROPAGATES to component.ts's containment boundary — the SAME
|
|
88
|
-
* boundary as a setup throw (ADR 0030.2 T6, code N402): remaining callbacks
|
|
89
|
-
* are skipped, the partial scope (including cleanups already registered by
|
|
90
|
-
* earlier callbacks) is disposed, the error fallback renders, and the host is
|
|
91
|
-
* stamped `data-nisli-error`. The pre-T6 behavior (console-and-limp per
|
|
92
|
-
* callback) left a half-mounted component alive with no machine-readable
|
|
93
|
-
* trace and no teardown — the one containment semantics setup already had
|
|
94
|
-
* (issue 0010) now covers mount too.
|
|
95
|
-
* @internal
|
|
96
|
-
*/
|
|
97
|
-
export function runMountCallbacks(comp) {
|
|
98
|
-
const callbacks = mountCallbacks.get(comp);
|
|
99
|
-
if (!callbacks)
|
|
100
|
-
return;
|
|
101
|
-
try {
|
|
102
|
-
for (const cb of callbacks) {
|
|
103
|
-
const cleanup = cb();
|
|
104
|
-
if (typeof cleanup === 'function') {
|
|
105
|
-
// Register cleanup as a disposer on the component
|
|
106
|
-
comp.addDisposer(cleanup);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
finally {
|
|
111
|
-
// Clear — mount callbacks run once (also when a throw contains the scope:
|
|
112
|
-
// the boundary re-runs setup from scratch on the next mount, which
|
|
113
|
-
// re-registers a fresh callback list).
|
|
114
|
-
mountCallbacks.delete(comp);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
//# sourceMappingURL=lifecycle.js.map
|
package/dist/lifecycle.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAE/D,uEAAuE;AAEvE,wFAAwF;AACxF,MAAM,cAAc,GAAG,IAAI,OAAO,EAAyC,CAAC;AAE5E;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,QAAmC;IACzD,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,oCAAoC;YACpC,wDAAwD,CACzD,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;IACnC,IAAI,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,SAAS,GAAG,EAAE,CAAC;QACf,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;IACD,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,QAAoB;IAC5C,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,sCAAsC;YACtC,wDAAwD,CACzD,CAAC;IACJ,CAAC;IACD,mBAAmB,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAmB,EACnB,SAAiB,EACjB,OAA2B;IAE3B,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,yCAAyC;YACzC,wDAAwD,CACzD,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAwB,CAAC,CAAC;IAC7D,mBAAmB,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QACrC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAwB,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS;QAAE,OAAO;IAEvB,IAAI,CAAC;QACH,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,EAAE,EAAE,CAAC;YACrB,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAClC,kDAAkD;gBACjD,IAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,0EAA0E;QAC1E,mEAAmE;QACnE,uCAAuC;QACvC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
|
package/dist/projection.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* projection.ts — First-class content projection (ADR 0025 item 1)
|
|
3
|
-
*
|
|
4
|
-
* `children(fallback?)` is a setup-context primitive that owns the light-DOM
|
|
5
|
-
* projection machinery the registry currently hand-rolls
|
|
6
|
-
* (captureChildren/projectChildren + per-component conditional-default swaps).
|
|
7
|
-
*
|
|
8
|
-
* ```ts
|
|
9
|
-
* component('ui-button', (props, host) => {
|
|
10
|
-
* transparentHost(host);
|
|
11
|
-
* return html`<button class="${classes}">${children()}</button>`;
|
|
12
|
-
* });
|
|
13
|
-
* ```
|
|
14
|
-
*
|
|
15
|
-
* Semantics:
|
|
16
|
-
* - Returns a reactive slot value (a signal) that a template interpolates. The
|
|
17
|
-
* slot resolves, in priority order: the factory `children` prop → the host's
|
|
18
|
-
* captured light-DOM children → the fallback.
|
|
19
|
-
* - Factory `children` route through the SAME slot: `children()` READS the
|
|
20
|
-
* host's `children` prop signal (sugar over one path). Crucially it renders
|
|
21
|
-
* them AT the slot position (not by relocating them to light DOM), so a
|
|
22
|
-
* factory-composed child element is a DOM descendant of its parent when its
|
|
23
|
-
* connectedCallback runs — `closest()`-based parent lookup keeps working.
|
|
24
|
-
* - Plain-HTML light-DOM children are captured pre-setup by component.ts
|
|
25
|
-
* (SEED → CAPTURE → CONTEXT) and projected here; late parser children are
|
|
26
|
-
* swept in a microtask (the ADR 0023 streaming machinery, now in core).
|
|
27
|
-
* - `children(fallback)` renders `fallback` when no MEANINGFUL children exist
|
|
28
|
-
* (whitespace-only light DOM does not count) and REPLACES it reactively when
|
|
29
|
-
* children arrive — including late parser children. This natively solves the
|
|
30
|
-
* conditional-default class (message-scroller-button's default glyph).
|
|
31
|
-
* - Single default slot only; named/multiple slots are a later design (v1 OUT).
|
|
32
|
-
*
|
|
33
|
-
* Zero-cost when unused: component.ts only snapshots childNodes when the host
|
|
34
|
-
* has any, and only children() consumes them.
|
|
35
|
-
*/
|
|
36
|
-
import { getCurrentComponent } from './context.js';
|
|
37
|
-
import { onCleanup } from './lifecycle.js';
|
|
38
|
-
import { signal, computed, flush } from './signal.js';
|
|
39
|
-
/** True if the nodes carry meaningful content (element or non-blank text). */
|
|
40
|
-
function isMeaningful(nodes) {
|
|
41
|
-
return nodes.some((n) => n.nodeType === 1 || (n.nodeType === 3 && (n.textContent ?? '').trim() !== ''));
|
|
42
|
-
}
|
|
43
|
-
/** A minimal TemplateResult that mounts pre-existing DOM nodes into the slot. */
|
|
44
|
-
function nodesTemplate(nodes) {
|
|
45
|
-
return {
|
|
46
|
-
__templateResult: true,
|
|
47
|
-
mount(w) {
|
|
48
|
-
for (const node of nodes)
|
|
49
|
-
w.appendChild(node);
|
|
50
|
-
},
|
|
51
|
-
dispose() { },
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
/** A re-mountable TemplateResult that renders a primitive as a fresh text node. */
|
|
55
|
-
function textTemplate(text) {
|
|
56
|
-
return {
|
|
57
|
-
__templateResult: true,
|
|
58
|
-
mount(w) {
|
|
59
|
-
w.appendChild(document.createTextNode(text));
|
|
60
|
-
},
|
|
61
|
-
dispose() { },
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Normalize a slot value so the template ALWAYS sees a TemplateResult / factory
|
|
66
|
-
* / array / null — never a bare primitive. Projection values may be detached
|
|
67
|
-
* and reinserted as fallback/light-DOM ownership changes, so wrapping primitive
|
|
68
|
-
* text keeps that projection value explicitly re-mountable.
|
|
69
|
-
*/
|
|
70
|
-
function asSlot(value) {
|
|
71
|
-
if (value == null || value === '')
|
|
72
|
-
return null;
|
|
73
|
-
if (typeof value === 'object'
|
|
74
|
-
&& ('__templateResult' in value || '__type' in value)) {
|
|
75
|
-
return value;
|
|
76
|
-
}
|
|
77
|
-
if (Array.isArray(value))
|
|
78
|
-
return value;
|
|
79
|
-
return textTemplate(String(value));
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Project the host's children (factory `children` prop or light DOM) into this
|
|
83
|
-
* slot, with an optional `fallback` rendered when empty. Must be called in
|
|
84
|
-
* setup context. Interpolate the result in a template:
|
|
85
|
-
* `html`<button>${children()}</button>``.
|
|
86
|
-
*/
|
|
87
|
-
export function children(fallback) {
|
|
88
|
-
const host = getCurrentComponent().element;
|
|
89
|
-
// Consume the pre-setup light-DOM capture; remove those nodes from the host
|
|
90
|
-
// so the rendered template doesn't duplicate them.
|
|
91
|
-
const captured = host.__capturedChildren ?? [];
|
|
92
|
-
host.__capturedChildren = undefined;
|
|
93
|
-
for (const node of captured) {
|
|
94
|
-
if (node.parentNode === host)
|
|
95
|
-
host.removeChild(node);
|
|
96
|
-
}
|
|
97
|
-
// The factory `children` prop, folded into the same slot (sugar over one path).
|
|
98
|
-
const childrenProp = host._propSignal ? host._propSignal('children') : undefined;
|
|
99
|
-
// Projected light-DOM nodes; grows when the late-parser sweep finds more.
|
|
100
|
-
const projectedNodes = signal(captured);
|
|
101
|
-
// True once this setup scope has been disposed (true disconnect, HMR
|
|
102
|
-
// teardown, OR the containment boundary tearing down a failed mount). The
|
|
103
|
-
// queued sweep below must then no-op: it would otherwise misread the
|
|
104
|
-
// post-teardown host children (restored light DOM, or the error fallback)
|
|
105
|
-
// as "late" and relocate them into a dead slot.
|
|
106
|
-
let disposed = false;
|
|
107
|
-
// A true disconnect/HMR teardown clears the component-owned rendered tree
|
|
108
|
-
// before setup runs again. Hand the plain light-DOM nodes back to component.ts
|
|
109
|
-
// so it can restore them as direct host children for the next capture.
|
|
110
|
-
onCleanup(() => {
|
|
111
|
-
disposed = true;
|
|
112
|
-
const nodes = projectedNodes.value;
|
|
113
|
-
host.__capturedChildren = nodes.length ? nodes : undefined;
|
|
114
|
-
});
|
|
115
|
-
// LATE-CHILDREN SWEEP — scheduled by component.ts's dedicated projection
|
|
116
|
-
// phase (ADR 0030.2 §3), which runs after the template is committed and
|
|
117
|
-
// BEFORE any onMount callback. Pre-0030.2 this was registered via
|
|
118
|
-
// children()'s own onMount, so the rendered-roots snapshot depended on
|
|
119
|
-
// where children() sat relative to other onMount() registrations (the 0025
|
|
120
|
-
// batch-3B ordering trap). Hoisting the SCHEDULING makes the rule
|
|
121
|
-
// universal: the snapshot is exactly the rendered template roots, and
|
|
122
|
-
// anything appearing after it — late parser/innerHTML children AND onMount
|
|
123
|
-
// host-appends — classifies as projected content. Only scheduling moved;
|
|
124
|
-
// the prop READ path (the computed below) is unchanged.
|
|
125
|
-
host.__nisliProjectionSweep = () => {
|
|
126
|
-
// The host's direct children at phase time are the rendered template
|
|
127
|
-
// roots. Anything that appears later is late projected content.
|
|
128
|
-
const renderedRoots = new Set(Array.from(host.childNodes));
|
|
129
|
-
queueMicrotask(() => {
|
|
130
|
-
if (disposed)
|
|
131
|
-
return; // scope torn down before the sweep ran
|
|
132
|
-
const late = Array.from(host.childNodes).filter((n) => !renderedRoots.has(n));
|
|
133
|
-
if (late.length && isMeaningful(late)) {
|
|
134
|
-
for (const node of late)
|
|
135
|
-
host.removeChild(node);
|
|
136
|
-
projectedNodes.value = [...projectedNodes.value, ...late];
|
|
137
|
-
// Flush the slot effect NOW so the late children land in this same
|
|
138
|
-
// microtask — the projectChildren() this replaces mutated the DOM
|
|
139
|
-
// imperatively, so callers only await one microtask for the sweep.
|
|
140
|
-
flush();
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
};
|
|
144
|
-
// Stable, RE-MOUNTABLE fallback slot: the same slot object is returned on
|
|
145
|
-
// every empty render, and it can be mounted → unmounted → mounted again
|
|
146
|
-
// (empty → filled → empty) without crashing. A string wraps to a fresh text
|
|
147
|
-
// node each mount. A TemplateResult is mounted ONCE here into a detached
|
|
148
|
-
// holder (its reactive bindings run in this component's context and dispose
|
|
149
|
-
// with it); its rendered nodes are then exposed as a re-mountable node slot,
|
|
150
|
-
// so the engine can detach and re-append them freely.
|
|
151
|
-
let fallbackSlot = null;
|
|
152
|
-
if (fallback != null) {
|
|
153
|
-
if (typeof fallback === 'string') {
|
|
154
|
-
fallbackSlot = textTemplate(fallback);
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
const holder = document.createDocumentFragment();
|
|
158
|
-
fallback.mount(holder);
|
|
159
|
-
const fallbackNodes = Array.from(holder.childNodes);
|
|
160
|
-
onCleanup(() => { try {
|
|
161
|
-
fallback.dispose();
|
|
162
|
-
}
|
|
163
|
-
catch (_) { /* ignore */ } });
|
|
164
|
-
fallbackSlot = nodesTemplate(fallbackNodes);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
// Priority: factory children → captured/late light DOM → fallback. Reactive,
|
|
168
|
-
// so late children (or a changing `children` prop) replace the fallback.
|
|
169
|
-
return computed(() => {
|
|
170
|
-
const kids = childrenProp?.value;
|
|
171
|
-
if (kids != null && kids !== '')
|
|
172
|
-
return asSlot(kids);
|
|
173
|
-
const nodes = projectedNodes.value;
|
|
174
|
-
if (isMeaningful(nodes))
|
|
175
|
-
return nodesTemplate(nodes);
|
|
176
|
-
return fallbackSlot;
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
//# sourceMappingURL=projection.js.map
|
package/dist/projection.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"projection.js","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":"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"}
|