native-sfc 0.0.2 → 0.0.3
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 +10 -1
- package/dist/index.bundled.js +36 -14
- package/dist/index.cdn.js +36 -14
- package/dist/index.d.ts +4 -0
- package/dist/index.js +36 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ Load a single HTML file as a Web Component.
|
|
|
11
11
|
</script>
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
Use `export default` to declare the component class.
|
|
15
|
+
|
|
14
16
|
```html
|
|
15
17
|
<!-- my-counter.html -->
|
|
16
18
|
<button @click="setCount(count() + 1)">Count is: {{ count() }}</button>
|
|
@@ -21,8 +23,15 @@ Load a single HTML file as a Web Component.
|
|
|
21
23
|
const [count, setCount] = signal(0);
|
|
22
24
|
return { count, setCount };
|
|
23
25
|
}
|
|
24
|
-
connectedCallback() {}
|
|
26
|
+
connectedCallback() {/* TODO */}
|
|
25
27
|
}
|
|
28
|
+
// OR
|
|
29
|
+
import { defineComponent } from "https://esm.sh/native-sfc";
|
|
30
|
+
export default defineComponent(({ onConnected }) => {
|
|
31
|
+
const [count, setCount] = signal(0);
|
|
32
|
+
onConnected(() => {/* TODO */});
|
|
33
|
+
return { count, setCount };
|
|
34
|
+
});
|
|
26
35
|
</script>
|
|
27
36
|
```
|
|
28
37
|
|
package/dist/index.bundled.js
CHANGED
|
@@ -2071,6 +2071,7 @@ ${code}`,
|
|
|
2071
2071
|
on
|
|
2072
2072
|
};
|
|
2073
2073
|
Object.preventExtensions(config);
|
|
2074
|
+
var bind = (fn, thisArg) => fn.bind(thisArg);
|
|
2074
2075
|
|
|
2075
2076
|
// src/rewriter.ts
|
|
2076
2077
|
async function rewriteModule(code, sourceUrl) {
|
|
@@ -2222,6 +2223,15 @@ var EffectScope = class {
|
|
|
2222
2223
|
}
|
|
2223
2224
|
};
|
|
2224
2225
|
var activeScope = null;
|
|
2226
|
+
function untrack(fn) {
|
|
2227
|
+
const prevEffect = activeEffect;
|
|
2228
|
+
activeEffect = null;
|
|
2229
|
+
try {
|
|
2230
|
+
return fn();
|
|
2231
|
+
} finally {
|
|
2232
|
+
activeEffect = prevEffect;
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2225
2235
|
function effectScope(fn) {
|
|
2226
2236
|
const scope = new EffectScope();
|
|
2227
2237
|
if (fn) scope.run(fn);
|
|
@@ -2374,11 +2384,15 @@ function reactiveNodes(nodes, context) {
|
|
|
2374
2384
|
const ctx = typeof context === "object" ? Object.assign({}, context, additionalContext) : additionalContext;
|
|
2375
2385
|
const keys = Object.keys(ctx);
|
|
2376
2386
|
const values = Object.values(ctx);
|
|
2377
|
-
|
|
2378
|
-
|
|
2387
|
+
try {
|
|
2388
|
+
const func = new Function(...keys, `return ${expr.trimStart()}`);
|
|
2389
|
+
return func(...values);
|
|
2390
|
+
} catch (error) {
|
|
2391
|
+
warn(`Failed to evaluate expression: "${expr}"`, error);
|
|
2392
|
+
}
|
|
2379
2393
|
};
|
|
2380
2394
|
const recursive = (nodes2) => {
|
|
2381
|
-
for (const node of nodes2) {
|
|
2395
|
+
for (const node of Array.from(nodes2)) {
|
|
2382
2396
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
2383
2397
|
const element = node;
|
|
2384
2398
|
const ifAttr = element.getAttribute("#if");
|
|
@@ -2447,7 +2461,7 @@ function reactiveNodes(nodes, context) {
|
|
|
2447
2461
|
const expr = attr.value;
|
|
2448
2462
|
effect(() => {
|
|
2449
2463
|
const value = evalExpr(expr);
|
|
2450
|
-
Reflect.set(element, propName, value);
|
|
2464
|
+
untrack(() => Reflect.set(element, propName, value));
|
|
2451
2465
|
});
|
|
2452
2466
|
element.removeAttribute(attr.name);
|
|
2453
2467
|
} else if (attr.name.startsWith(":")) {
|
|
@@ -2455,7 +2469,7 @@ function reactiveNodes(nodes, context) {
|
|
|
2455
2469
|
const expr = attr.value;
|
|
2456
2470
|
effect(() => {
|
|
2457
2471
|
const value = evalExpr(expr);
|
|
2458
|
-
element.setAttribute(attrName, value);
|
|
2472
|
+
untrack(() => element.setAttribute(attrName, value));
|
|
2459
2473
|
});
|
|
2460
2474
|
element.removeAttribute(attr.name);
|
|
2461
2475
|
} else if (attr.name.startsWith("@")) {
|
|
@@ -2486,7 +2500,7 @@ function reactiveNodes(nodes, context) {
|
|
|
2486
2500
|
if (part.type === "dynamic") {
|
|
2487
2501
|
effect(() => {
|
|
2488
2502
|
const value = evalExpr(part.content);
|
|
2489
|
-
newTextNode.textContent = String(value);
|
|
2503
|
+
untrack(() => newTextNode.textContent = String(value));
|
|
2490
2504
|
});
|
|
2491
2505
|
}
|
|
2492
2506
|
}
|
|
@@ -2579,26 +2593,30 @@ function defineComponent(setup) {
|
|
|
2579
2593
|
_onConnectedEvents = [];
|
|
2580
2594
|
_onDisconnectedEvents = [];
|
|
2581
2595
|
setup() {
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2596
|
+
const setup22 = bind(setup, this);
|
|
2597
|
+
return setup22({
|
|
2598
|
+
onConnected: (event) => this._onConnectedEvents.push(bind(event, this)),
|
|
2599
|
+
onDisconnected: (event) => this._onDisconnectedEvents.push(bind(event, this))
|
|
2585
2600
|
});
|
|
2586
2601
|
}
|
|
2587
2602
|
connectedCallback() {
|
|
2588
2603
|
const root = this.shadowRoot || this.attachShadow({ mode: "open" });
|
|
2589
|
-
this._onConnectedEvents.forEach((cb) => cb
|
|
2604
|
+
untrack(() => this._onConnectedEvents.forEach((cb) => cb(root)));
|
|
2590
2605
|
}
|
|
2591
2606
|
disconnectedCallback() {
|
|
2592
2607
|
const root = this.shadowRoot;
|
|
2593
|
-
this._onDisconnectedEvents.forEach((cb) => cb
|
|
2608
|
+
untrack(() => this._onDisconnectedEvents.forEach((cb) => cb(root)));
|
|
2594
2609
|
}
|
|
2595
2610
|
};
|
|
2596
2611
|
}
|
|
2597
|
-
|
|
2598
|
-
|
|
2612
|
+
const setup2 = bind(setup, void 0);
|
|
2613
|
+
const context = setup2({
|
|
2614
|
+
onConnected: (cb) => queueMicrotask(() => cb(document)),
|
|
2599
2615
|
onDisconnected: () => {
|
|
2600
2616
|
}
|
|
2601
2617
|
});
|
|
2618
|
+
reactiveNodes(document.body.childNodes, context);
|
|
2619
|
+
return;
|
|
2602
2620
|
}
|
|
2603
2621
|
function filterGlobalStyle(doc) {
|
|
2604
2622
|
for (const styleElement of doc.querySelectorAll("style")) {
|
|
@@ -2687,7 +2705,11 @@ export {
|
|
|
2687
2705
|
effect,
|
|
2688
2706
|
effectScope,
|
|
2689
2707
|
loadComponent,
|
|
2690
|
-
signal
|
|
2708
|
+
signal,
|
|
2709
|
+
untrack
|
|
2691
2710
|
};
|
|
2692
2711
|
//! we provide an extra argument to user's component constructor
|
|
2693
2712
|
//! if the user's constructor does not create a shadow root, we will create one here
|
|
2713
|
+
//! we bind `this` to the setup function, so that users can access `this` in setup, and `this` is the component instance
|
|
2714
|
+
//! `this` is undefined in normal document context's setup function
|
|
2715
|
+
//! make the document.body reactive, just like the web component (defined at `extendsElement`)
|
package/dist/index.cdn.js
CHANGED
|
@@ -28,6 +28,7 @@ ${code}`,
|
|
|
28
28
|
on
|
|
29
29
|
};
|
|
30
30
|
Object.preventExtensions(config);
|
|
31
|
+
var bind = (fn, thisArg) => fn.bind(thisArg);
|
|
31
32
|
|
|
32
33
|
// src/rewriter.ts
|
|
33
34
|
async function rewriteModule(code, sourceUrl) {
|
|
@@ -179,6 +180,15 @@ var EffectScope = class {
|
|
|
179
180
|
}
|
|
180
181
|
};
|
|
181
182
|
var activeScope = null;
|
|
183
|
+
function untrack(fn) {
|
|
184
|
+
const prevEffect = activeEffect;
|
|
185
|
+
activeEffect = null;
|
|
186
|
+
try {
|
|
187
|
+
return fn();
|
|
188
|
+
} finally {
|
|
189
|
+
activeEffect = prevEffect;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
182
192
|
function effectScope(fn) {
|
|
183
193
|
const scope = new EffectScope();
|
|
184
194
|
if (fn) scope.run(fn);
|
|
@@ -331,11 +341,15 @@ function reactiveNodes(nodes, context) {
|
|
|
331
341
|
const ctx = typeof context === "object" ? Object.assign({}, context, additionalContext) : additionalContext;
|
|
332
342
|
const keys = Object.keys(ctx);
|
|
333
343
|
const values = Object.values(ctx);
|
|
334
|
-
|
|
335
|
-
|
|
344
|
+
try {
|
|
345
|
+
const func = new Function(...keys, `return ${expr.trimStart()}`);
|
|
346
|
+
return func(...values);
|
|
347
|
+
} catch (error) {
|
|
348
|
+
warn(`Failed to evaluate expression: "${expr}"`, error);
|
|
349
|
+
}
|
|
336
350
|
};
|
|
337
351
|
const recursive = (nodes2) => {
|
|
338
|
-
for (const node of nodes2) {
|
|
352
|
+
for (const node of Array.from(nodes2)) {
|
|
339
353
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
340
354
|
const element = node;
|
|
341
355
|
const ifAttr = element.getAttribute("#if");
|
|
@@ -404,7 +418,7 @@ function reactiveNodes(nodes, context) {
|
|
|
404
418
|
const expr = attr.value;
|
|
405
419
|
effect(() => {
|
|
406
420
|
const value = evalExpr(expr);
|
|
407
|
-
Reflect.set(element, propName, value);
|
|
421
|
+
untrack(() => Reflect.set(element, propName, value));
|
|
408
422
|
});
|
|
409
423
|
element.removeAttribute(attr.name);
|
|
410
424
|
} else if (attr.name.startsWith(":")) {
|
|
@@ -412,7 +426,7 @@ function reactiveNodes(nodes, context) {
|
|
|
412
426
|
const expr = attr.value;
|
|
413
427
|
effect(() => {
|
|
414
428
|
const value = evalExpr(expr);
|
|
415
|
-
element.setAttribute(attrName, value);
|
|
429
|
+
untrack(() => element.setAttribute(attrName, value));
|
|
416
430
|
});
|
|
417
431
|
element.removeAttribute(attr.name);
|
|
418
432
|
} else if (attr.name.startsWith("@")) {
|
|
@@ -443,7 +457,7 @@ function reactiveNodes(nodes, context) {
|
|
|
443
457
|
if (part.type === "dynamic") {
|
|
444
458
|
effect(() => {
|
|
445
459
|
const value = evalExpr(part.content);
|
|
446
|
-
newTextNode.textContent = String(value);
|
|
460
|
+
untrack(() => newTextNode.textContent = String(value));
|
|
447
461
|
});
|
|
448
462
|
}
|
|
449
463
|
}
|
|
@@ -536,26 +550,30 @@ function defineComponent(setup) {
|
|
|
536
550
|
_onConnectedEvents = [];
|
|
537
551
|
_onDisconnectedEvents = [];
|
|
538
552
|
setup() {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
553
|
+
const setup22 = bind(setup, this);
|
|
554
|
+
return setup22({
|
|
555
|
+
onConnected: (event) => this._onConnectedEvents.push(bind(event, this)),
|
|
556
|
+
onDisconnected: (event) => this._onDisconnectedEvents.push(bind(event, this))
|
|
542
557
|
});
|
|
543
558
|
}
|
|
544
559
|
connectedCallback() {
|
|
545
560
|
const root = this.shadowRoot || this.attachShadow({ mode: "open" });
|
|
546
|
-
this._onConnectedEvents.forEach((cb) => cb
|
|
561
|
+
untrack(() => this._onConnectedEvents.forEach((cb) => cb(root)));
|
|
547
562
|
}
|
|
548
563
|
disconnectedCallback() {
|
|
549
564
|
const root = this.shadowRoot;
|
|
550
|
-
this._onDisconnectedEvents.forEach((cb) => cb
|
|
565
|
+
untrack(() => this._onDisconnectedEvents.forEach((cb) => cb(root)));
|
|
551
566
|
}
|
|
552
567
|
};
|
|
553
568
|
}
|
|
554
|
-
|
|
555
|
-
|
|
569
|
+
const setup2 = bind(setup, void 0);
|
|
570
|
+
const context = setup2({
|
|
571
|
+
onConnected: (cb) => queueMicrotask(() => cb(document)),
|
|
556
572
|
onDisconnected: () => {
|
|
557
573
|
}
|
|
558
574
|
});
|
|
575
|
+
reactiveNodes(document.body.childNodes, context);
|
|
576
|
+
return;
|
|
559
577
|
}
|
|
560
578
|
function filterGlobalStyle(doc) {
|
|
561
579
|
for (const styleElement of doc.querySelectorAll("style")) {
|
|
@@ -644,7 +662,11 @@ export {
|
|
|
644
662
|
effect,
|
|
645
663
|
effectScope,
|
|
646
664
|
loadComponent,
|
|
647
|
-
signal
|
|
665
|
+
signal,
|
|
666
|
+
untrack
|
|
648
667
|
};
|
|
649
668
|
//! we provide an extra argument to user's component constructor
|
|
650
669
|
//! if the user's constructor does not create a shadow root, we will create one here
|
|
670
|
+
//! we bind `this` to the setup function, so that users can access `this` in setup, and `this` is the component instance
|
|
671
|
+
//! `this` is undefined in normal document context's setup function
|
|
672
|
+
//! make the document.body reactive, just like the web component (defined at `extendsElement`)
|
package/dist/index.d.ts
CHANGED
|
@@ -98,6 +98,9 @@ export type NativeSFCEventsMap = {
|
|
|
98
98
|
[K in keyof NativeSFCEvents]: CustomEvent<NativeSFCEvents[K]>;
|
|
99
99
|
};
|
|
100
100
|
declare function on<K extends keyof NativeSFCEvents>(eventName: K, listener: (ev: NativeSFCEventsMap[K]) => any): () => void;
|
|
101
|
+
/**
|
|
102
|
+
* The global configuration object for the library.
|
|
103
|
+
*/
|
|
101
104
|
export declare const config: {
|
|
102
105
|
fetch: typeof fetch;
|
|
103
106
|
rewriteModule: (code: string, sourceUrl: string) => Awaitable<string>;
|
|
@@ -109,6 +112,7 @@ export declare class NativeSFCError extends Error {
|
|
|
109
112
|
}
|
|
110
113
|
export type Getter<T> = () => T;
|
|
111
114
|
export type Setter<T> = (newValue: T) => void;
|
|
115
|
+
export declare function untrack<T>(fn: () => T): T;
|
|
112
116
|
export declare function effectScope(fn?: VoidFunction): VoidFunction;
|
|
113
117
|
export declare function effect(fn: VoidFunction): VoidFunction;
|
|
114
118
|
export declare function signal<T>(initialValue: T): readonly [
|
package/dist/index.js
CHANGED
|
@@ -28,6 +28,7 @@ ${code}`,
|
|
|
28
28
|
on
|
|
29
29
|
};
|
|
30
30
|
Object.preventExtensions(config);
|
|
31
|
+
var bind = (fn, thisArg) => fn.bind(thisArg);
|
|
31
32
|
|
|
32
33
|
// src/rewriter.ts
|
|
33
34
|
async function rewriteModule(code, sourceUrl) {
|
|
@@ -179,6 +180,15 @@ var EffectScope = class {
|
|
|
179
180
|
}
|
|
180
181
|
};
|
|
181
182
|
var activeScope = null;
|
|
183
|
+
function untrack(fn) {
|
|
184
|
+
const prevEffect = activeEffect;
|
|
185
|
+
activeEffect = null;
|
|
186
|
+
try {
|
|
187
|
+
return fn();
|
|
188
|
+
} finally {
|
|
189
|
+
activeEffect = prevEffect;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
182
192
|
function effectScope(fn) {
|
|
183
193
|
const scope = new EffectScope();
|
|
184
194
|
if (fn) scope.run(fn);
|
|
@@ -331,11 +341,15 @@ function reactiveNodes(nodes, context) {
|
|
|
331
341
|
const ctx = typeof context === "object" ? Object.assign({}, context, additionalContext) : additionalContext;
|
|
332
342
|
const keys = Object.keys(ctx);
|
|
333
343
|
const values = Object.values(ctx);
|
|
334
|
-
|
|
335
|
-
|
|
344
|
+
try {
|
|
345
|
+
const func = new Function(...keys, `return ${expr.trimStart()}`);
|
|
346
|
+
return func(...values);
|
|
347
|
+
} catch (error) {
|
|
348
|
+
warn(`Failed to evaluate expression: "${expr}"`, error);
|
|
349
|
+
}
|
|
336
350
|
};
|
|
337
351
|
const recursive = (nodes2) => {
|
|
338
|
-
for (const node of nodes2) {
|
|
352
|
+
for (const node of Array.from(nodes2)) {
|
|
339
353
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
340
354
|
const element = node;
|
|
341
355
|
const ifAttr = element.getAttribute("#if");
|
|
@@ -404,7 +418,7 @@ function reactiveNodes(nodes, context) {
|
|
|
404
418
|
const expr = attr.value;
|
|
405
419
|
effect(() => {
|
|
406
420
|
const value = evalExpr(expr);
|
|
407
|
-
Reflect.set(element, propName, value);
|
|
421
|
+
untrack(() => Reflect.set(element, propName, value));
|
|
408
422
|
});
|
|
409
423
|
element.removeAttribute(attr.name);
|
|
410
424
|
} else if (attr.name.startsWith(":")) {
|
|
@@ -412,7 +426,7 @@ function reactiveNodes(nodes, context) {
|
|
|
412
426
|
const expr = attr.value;
|
|
413
427
|
effect(() => {
|
|
414
428
|
const value = evalExpr(expr);
|
|
415
|
-
element.setAttribute(attrName, value);
|
|
429
|
+
untrack(() => element.setAttribute(attrName, value));
|
|
416
430
|
});
|
|
417
431
|
element.removeAttribute(attr.name);
|
|
418
432
|
} else if (attr.name.startsWith("@")) {
|
|
@@ -443,7 +457,7 @@ function reactiveNodes(nodes, context) {
|
|
|
443
457
|
if (part.type === "dynamic") {
|
|
444
458
|
effect(() => {
|
|
445
459
|
const value = evalExpr(part.content);
|
|
446
|
-
newTextNode.textContent = String(value);
|
|
460
|
+
untrack(() => newTextNode.textContent = String(value));
|
|
447
461
|
});
|
|
448
462
|
}
|
|
449
463
|
}
|
|
@@ -536,26 +550,30 @@ function defineComponent(setup) {
|
|
|
536
550
|
_onConnectedEvents = [];
|
|
537
551
|
_onDisconnectedEvents = [];
|
|
538
552
|
setup() {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
553
|
+
const setup22 = bind(setup, this);
|
|
554
|
+
return setup22({
|
|
555
|
+
onConnected: (event) => this._onConnectedEvents.push(bind(event, this)),
|
|
556
|
+
onDisconnected: (event) => this._onDisconnectedEvents.push(bind(event, this))
|
|
542
557
|
});
|
|
543
558
|
}
|
|
544
559
|
connectedCallback() {
|
|
545
560
|
const root = this.shadowRoot || this.attachShadow({ mode: "open" });
|
|
546
|
-
this._onConnectedEvents.forEach((cb) => cb
|
|
561
|
+
untrack(() => this._onConnectedEvents.forEach((cb) => cb(root)));
|
|
547
562
|
}
|
|
548
563
|
disconnectedCallback() {
|
|
549
564
|
const root = this.shadowRoot;
|
|
550
|
-
this._onDisconnectedEvents.forEach((cb) => cb
|
|
565
|
+
untrack(() => this._onDisconnectedEvents.forEach((cb) => cb(root)));
|
|
551
566
|
}
|
|
552
567
|
};
|
|
553
568
|
}
|
|
554
|
-
|
|
555
|
-
|
|
569
|
+
const setup2 = bind(setup, void 0);
|
|
570
|
+
const context = setup2({
|
|
571
|
+
onConnected: (cb) => queueMicrotask(() => cb(document)),
|
|
556
572
|
onDisconnected: () => {
|
|
557
573
|
}
|
|
558
574
|
});
|
|
575
|
+
reactiveNodes(document.body.childNodes, context);
|
|
576
|
+
return;
|
|
559
577
|
}
|
|
560
578
|
function filterGlobalStyle(doc) {
|
|
561
579
|
for (const styleElement of doc.querySelectorAll("style")) {
|
|
@@ -644,7 +662,11 @@ export {
|
|
|
644
662
|
effect,
|
|
645
663
|
effectScope,
|
|
646
664
|
loadComponent,
|
|
647
|
-
signal
|
|
665
|
+
signal,
|
|
666
|
+
untrack
|
|
648
667
|
};
|
|
649
668
|
//! we provide an extra argument to user's component constructor
|
|
650
669
|
//! if the user's constructor does not create a shadow root, we will create one here
|
|
670
|
+
//! we bind `this` to the setup function, so that users can access `this` in setup, and `this` is the component instance
|
|
671
|
+
//! `this` is undefined in normal document context's setup function
|
|
672
|
+
//! make the document.body reactive, just like the web component (defined at `extendsElement`)
|