@fictjs/runtime 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.cjs +9 -9
- package/dist/advanced.d.cts +4 -4
- package/dist/advanced.d.ts +4 -4
- package/dist/advanced.js +4 -4
- package/dist/{binding-BWchH3Kp.d.cts → binding-DcnhUSQK.d.ts} +5 -3
- package/dist/{binding-BWchH3Kp.d.ts → binding-FRyTeLDn.d.cts} +5 -3
- package/dist/{chunk-FVX77557.js → chunk-2UR2UWE2.js} +3 -3
- package/dist/{chunk-LBE6DC3V.cjs → chunk-44EQF3AR.cjs} +63 -52
- package/dist/chunk-44EQF3AR.cjs.map +1 -0
- package/dist/{chunk-OAM7HABA.cjs → chunk-4QGEN5SJ.cjs} +340 -263
- package/dist/chunk-4QGEN5SJ.cjs.map +1 -0
- package/dist/{chunk-PD6IQY2Y.cjs → chunk-C5IE4WUG.cjs} +8 -8
- package/dist/{chunk-PD6IQY2Y.cjs.map → chunk-C5IE4WUG.cjs.map} +1 -1
- package/dist/{chunk-DXG3TARY.js → chunk-DIK33H5U.js} +202 -30
- package/dist/chunk-DIK33H5U.js.map +1 -0
- package/dist/{chunk-JVYH76ZX.js → chunk-FESAXMHT.js} +7 -6
- package/dist/{chunk-JVYH76ZX.js.map → chunk-FESAXMHT.js.map} +1 -1
- package/dist/chunk-FHQZCAAK.cjs +112 -0
- package/dist/chunk-FHQZCAAK.cjs.map +1 -0
- package/dist/{chunk-UBFDB6OL.cjs → chunk-QNMYVXRL.cjs} +222 -50
- package/dist/chunk-QNMYVXRL.cjs.map +1 -0
- package/dist/{chunk-N6ODUM2Y.js → chunk-S63VBIWN.js} +27 -16
- package/dist/chunk-S63VBIWN.js.map +1 -0
- package/dist/{chunk-T2LNV5Q5.js → chunk-WIHNVN6L.js} +153 -76
- package/dist/chunk-WIHNVN6L.js.map +1 -0
- package/dist/{devtools-BDp76luf.d.ts → devtools-BtIkN77t.d.cts} +14 -2
- package/dist/{devtools-5AipK9CX.d.cts → devtools-D2z4llpA.d.ts} +14 -2
- package/dist/index.cjs +60 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.dev.js +300 -74
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/dist/internal-list.cjs +4 -4
- package/dist/internal-list.d.cts +2 -2
- package/dist/internal-list.d.ts +2 -2
- package/dist/internal-list.js +3 -3
- package/dist/internal.cjs +5 -5
- package/dist/internal.d.cts +6 -6
- package/dist/internal.d.ts +6 -6
- package/dist/internal.js +4 -4
- package/dist/jsx-dev-runtime.d.cts +671 -0
- package/dist/jsx-dev-runtime.d.ts +671 -0
- package/dist/jsx-runtime.d.cts +671 -0
- package/dist/jsx-runtime.d.ts +671 -0
- package/dist/{list-DL5DOFcO.d.ts → list-BKM6YOPq.d.ts} +2 -2
- package/dist/{list-hP7hQ9Vk.d.cts → list-Bi8dDF8Q.d.cts} +2 -2
- package/dist/loader.cjs +34 -28
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.d.cts +2 -2
- package/dist/loader.d.ts +2 -2
- package/dist/loader.js +17 -11
- package/dist/loader.js.map +1 -1
- package/dist/{props-BpZz0AOq.d.cts → props-9chMyBGb.d.cts} +2 -2
- package/dist/{props-CjLH0JE-.d.ts → props-D1nj2p_3.d.ts} +2 -2
- package/dist/{resume-BJ4oHLi_.d.cts → resume-C5IKAIdh.d.ts} +2 -2
- package/dist/{resume-CuyJWXP_.d.ts → resume-DPZxmA95.d.cts} +2 -2
- package/dist/{scope-jPt5DHRT.d.ts → scope-BSkhJr0a.d.ts} +1 -1
- package/dist/{scope-BJCtq8hJ.d.cts → scope-Bn3sxem5.d.cts} +1 -1
- package/dist/{signal-C4ISF17w.d.cts → signal-Z4KkDk9h.d.cts} +12 -1
- package/dist/{signal-C4ISF17w.d.ts → signal-Z4KkDk9h.d.ts} +12 -1
- package/package.json +2 -2
- package/src/binding.ts +59 -29
- package/src/context.ts +4 -3
- package/src/devtools.ts +19 -2
- package/src/dom.ts +122 -42
- package/src/effect.ts +5 -5
- package/src/error-boundary.ts +5 -5
- package/src/hooks.ts +13 -5
- package/src/lifecycle.ts +48 -3
- package/src/list-helpers.ts +30 -13
- package/src/loader.ts +20 -12
- package/src/node-ops.ts +8 -5
- package/src/signal.ts +191 -18
- package/src/suspense.ts +5 -4
- package/src/transition.ts +9 -3
- package/dist/chunk-DXG3TARY.js.map +0 -1
- package/dist/chunk-LBE6DC3V.cjs.map +0 -1
- package/dist/chunk-N6ODUM2Y.js.map +0 -1
- package/dist/chunk-OAM7HABA.cjs.map +0 -1
- package/dist/chunk-PG4QX2I2.cjs +0 -111
- package/dist/chunk-PG4QX2I2.cjs.map +0 -1
- package/dist/chunk-T2LNV5Q5.js.map +0 -1
- package/dist/chunk-UBFDB6OL.cjs.map +0 -1
- /package/dist/{chunk-FVX77557.js.map → chunk-2UR2UWE2.js.map} +0 -0
|
@@ -19,6 +19,17 @@ interface MemoOptions<T> {
|
|
|
19
19
|
name?: string;
|
|
20
20
|
/** Source location */
|
|
21
21
|
devToolsSource?: string;
|
|
22
|
+
/** Internal memo created by compiler runtime plumbing (hidden from DevTools) */
|
|
23
|
+
internal?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Options for creating an effect
|
|
27
|
+
*/
|
|
28
|
+
interface EffectOptions {
|
|
29
|
+
/** Debug name */
|
|
30
|
+
name?: string;
|
|
31
|
+
/** Source location */
|
|
32
|
+
devToolsSource?: string;
|
|
22
33
|
}
|
|
23
34
|
/**
|
|
24
35
|
* Signal accessor - function to get/set signal value
|
|
@@ -63,4 +74,4 @@ declare function __resetReactiveState(): void;
|
|
|
63
74
|
*/
|
|
64
75
|
declare function createSelector<T>(source: () => T, equalityFn?: (a: T, b: T) => boolean): (key: T) => boolean;
|
|
65
76
|
|
|
66
|
-
export { type ComputedAccessor as C, type MemoOptions as M, type SignalAccessor as S, __resetReactiveState as _, type SignalOptions as a, createSelector as c, effectScope as e, signal as s };
|
|
77
|
+
export { type ComputedAccessor as C, type EffectOptions as E, type MemoOptions as M, type SignalAccessor as S, __resetReactiveState as _, type SignalOptions as a, createSelector as c, effectScope as e, signal as s };
|
|
@@ -19,6 +19,17 @@ interface MemoOptions<T> {
|
|
|
19
19
|
name?: string;
|
|
20
20
|
/** Source location */
|
|
21
21
|
devToolsSource?: string;
|
|
22
|
+
/** Internal memo created by compiler runtime plumbing (hidden from DevTools) */
|
|
23
|
+
internal?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Options for creating an effect
|
|
27
|
+
*/
|
|
28
|
+
interface EffectOptions {
|
|
29
|
+
/** Debug name */
|
|
30
|
+
name?: string;
|
|
31
|
+
/** Source location */
|
|
32
|
+
devToolsSource?: string;
|
|
22
33
|
}
|
|
23
34
|
/**
|
|
24
35
|
* Signal accessor - function to get/set signal value
|
|
@@ -63,4 +74,4 @@ declare function __resetReactiveState(): void;
|
|
|
63
74
|
*/
|
|
64
75
|
declare function createSelector<T>(source: () => T, equalityFn?: (a: T, b: T) => boolean): (key: T) => boolean;
|
|
65
76
|
|
|
66
|
-
export { type ComputedAccessor as C, type MemoOptions as M, type SignalAccessor as S, __resetReactiveState as _, type SignalOptions as a, createSelector as c, effectScope as e, signal as s };
|
|
77
|
+
export { type ComputedAccessor as C, type EffectOptions as E, type MemoOptions as M, type SignalAccessor as S, __resetReactiveState as _, type SignalOptions as a, createSelector as c, effectScope as e, signal as s };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fictjs/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Fict reactive runtime",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"author": "unadlib",
|
|
71
71
|
"license": "MIT",
|
|
72
72
|
"scripts": {
|
|
73
|
-
"build": "tsup",
|
|
73
|
+
"build": "pnpm run clean && tsup",
|
|
74
74
|
"dev": "tsup --watch",
|
|
75
75
|
"test": "vitest run",
|
|
76
76
|
"test:stress": "FICT_RUNTIME_STRESS=1 vitest run test/runtime-stability.stress.test.ts",
|
package/src/binding.ts
CHANGED
|
@@ -302,8 +302,17 @@ export function callEventHandler(
|
|
|
302
302
|
* createTextBinding(() => $count())
|
|
303
303
|
* ```
|
|
304
304
|
*/
|
|
305
|
-
export function createTextBinding(
|
|
306
|
-
|
|
305
|
+
export function createTextBinding(
|
|
306
|
+
value: MaybeReactive<unknown>,
|
|
307
|
+
owner?: Document | Node | null,
|
|
308
|
+
): Text {
|
|
309
|
+
const textOwnerDocument =
|
|
310
|
+
owner && 'nodeType' in owner
|
|
311
|
+
? owner.nodeType === 9
|
|
312
|
+
? (owner as Document)
|
|
313
|
+
: ((owner as Node).ownerDocument ?? document)
|
|
314
|
+
: document
|
|
315
|
+
const text = textOwnerDocument.createTextNode('')
|
|
307
316
|
|
|
308
317
|
if (isReactive(value)) {
|
|
309
318
|
// Reactive: create effect to update text when value changes
|
|
@@ -706,6 +715,7 @@ export function insert(
|
|
|
706
715
|
createElementFn?: CreateElementFn,
|
|
707
716
|
): Cleanup {
|
|
708
717
|
const hostRoot = getCurrentRoot()
|
|
718
|
+
const parentOwnerDocument = parent.ownerDocument ?? document
|
|
709
719
|
let marker: Node
|
|
710
720
|
let ownsMarker = false
|
|
711
721
|
let createFn: CreateElementFn | undefined = createElementFn
|
|
@@ -714,11 +724,12 @@ export function insert(
|
|
|
714
724
|
marker = markerOrCreateElement
|
|
715
725
|
createFn = createElementFn
|
|
716
726
|
} else {
|
|
717
|
-
marker =
|
|
727
|
+
marker = parentOwnerDocument.createComment('fict:insert')
|
|
718
728
|
parent.appendChild(marker)
|
|
719
729
|
createFn = markerOrCreateElement as CreateElementFn | undefined
|
|
720
730
|
ownsMarker = true
|
|
721
731
|
}
|
|
732
|
+
const markerOwnerDocument = marker.ownerDocument ?? parentOwnerDocument
|
|
722
733
|
|
|
723
734
|
let currentNodes: Node[] = []
|
|
724
735
|
let currentText: Text | null = null
|
|
@@ -733,7 +744,7 @@ export function insert(
|
|
|
733
744
|
|
|
734
745
|
const setTextNode = (textValue: string, shouldInsert: boolean, parentNode: ParentNode & Node) => {
|
|
735
746
|
if (!currentText) {
|
|
736
|
-
currentText =
|
|
747
|
+
currentText = (parentNode.ownerDocument ?? markerOwnerDocument).createTextNode(textValue)
|
|
737
748
|
} else if (currentText.data !== textValue) {
|
|
738
749
|
currentText.data = textValue
|
|
739
750
|
}
|
|
@@ -789,6 +800,7 @@ export function insert(
|
|
|
789
800
|
let handledError = false
|
|
790
801
|
try {
|
|
791
802
|
let newNode: Node | Node[]
|
|
803
|
+
const ownerDocument = parentNode?.ownerDocument ?? markerOwnerDocument
|
|
792
804
|
|
|
793
805
|
if (value instanceof Node) {
|
|
794
806
|
newNode = value
|
|
@@ -799,18 +811,18 @@ export function insert(
|
|
|
799
811
|
if (createFn) {
|
|
800
812
|
const mapped: Node[] = []
|
|
801
813
|
for (const item of value) {
|
|
802
|
-
mapped.push(...toNodeArray(createFn(item as any)))
|
|
814
|
+
mapped.push(...toNodeArray(createFn(item as any), ownerDocument))
|
|
803
815
|
}
|
|
804
816
|
newNode = mapped
|
|
805
817
|
} else {
|
|
806
|
-
newNode =
|
|
818
|
+
newNode = ownerDocument.createTextNode(String(value))
|
|
807
819
|
}
|
|
808
820
|
}
|
|
809
821
|
} else {
|
|
810
|
-
newNode = createFn ? createFn(value) :
|
|
822
|
+
newNode = createFn ? createFn(value) : ownerDocument.createTextNode(String(value))
|
|
811
823
|
}
|
|
812
824
|
|
|
813
|
-
nodes = toNodeArray(newNode)
|
|
825
|
+
nodes = toNodeArray(newNode, ownerDocument)
|
|
814
826
|
if (root.suspended) {
|
|
815
827
|
handledError = true
|
|
816
828
|
destroyRoot(root)
|
|
@@ -867,6 +879,7 @@ export function insertBetween(
|
|
|
867
879
|
createElementFn?: CreateElementFn,
|
|
868
880
|
): Cleanup {
|
|
869
881
|
const hostRoot = getCurrentRoot()
|
|
882
|
+
const markerOwnerDocument = start.ownerDocument ?? end.ownerDocument ?? document
|
|
870
883
|
let currentNodes: Node[] = []
|
|
871
884
|
let currentText: Text | null = null
|
|
872
885
|
let currentRoot: RootContext | null = null
|
|
@@ -890,8 +903,9 @@ export function insertBetween(
|
|
|
890
903
|
}
|
|
891
904
|
|
|
892
905
|
const setTextNode = (textValue: string, shouldInsert: boolean) => {
|
|
906
|
+
const parentNode = start.parentNode as (ParentNode & Node) | null
|
|
893
907
|
if (!currentText) {
|
|
894
|
-
currentText =
|
|
908
|
+
currentText = (parentNode?.ownerDocument ?? markerOwnerDocument).createTextNode(textValue)
|
|
895
909
|
} else if (currentText.data !== textValue) {
|
|
896
910
|
currentText.data = textValue
|
|
897
911
|
}
|
|
@@ -906,7 +920,6 @@ export function insertBetween(
|
|
|
906
920
|
}
|
|
907
921
|
|
|
908
922
|
clearCurrentNodes()
|
|
909
|
-
const parentNode = start.parentNode as (ParentNode & Node) | null
|
|
910
923
|
if (parentNode) {
|
|
911
924
|
insertNodesBefore(parentNode, [currentText], end)
|
|
912
925
|
currentNodes = [currentText]
|
|
@@ -959,6 +972,7 @@ export function insertBetween(
|
|
|
959
972
|
let handledError = false
|
|
960
973
|
try {
|
|
961
974
|
let newNode: Node | Node[] = undefined as unknown as Node | Node[]
|
|
975
|
+
const ownerDocument = parentNode?.ownerDocument ?? markerOwnerDocument
|
|
962
976
|
const createValue = () => {
|
|
963
977
|
if (value instanceof Node) {
|
|
964
978
|
return value
|
|
@@ -970,24 +984,31 @@ export function insertBetween(
|
|
|
970
984
|
if (createElementFn) {
|
|
971
985
|
const mapped: Node[] = []
|
|
972
986
|
for (const item of value) {
|
|
973
|
-
mapped.push(...toNodeArray(createElementFn(item as any)))
|
|
987
|
+
mapped.push(...toNodeArray(createElementFn(item as any), ownerDocument))
|
|
974
988
|
}
|
|
975
989
|
return mapped
|
|
976
990
|
}
|
|
977
|
-
return
|
|
991
|
+
return ownerDocument.createTextNode(String(value))
|
|
978
992
|
}
|
|
979
|
-
return createElementFn
|
|
993
|
+
return createElementFn
|
|
994
|
+
? createElementFn(value)
|
|
995
|
+
: ownerDocument.createTextNode(String(value))
|
|
980
996
|
}
|
|
981
997
|
|
|
982
998
|
if (initialHydrating && isHydratingActive() && parentNode) {
|
|
983
|
-
withHydrationRange(
|
|
984
|
-
|
|
985
|
-
|
|
999
|
+
withHydrationRange(
|
|
1000
|
+
start.nextSibling,
|
|
1001
|
+
end,
|
|
1002
|
+
parentNode.ownerDocument ?? markerOwnerDocument,
|
|
1003
|
+
() => {
|
|
1004
|
+
newNode = createValue()
|
|
1005
|
+
},
|
|
1006
|
+
)
|
|
986
1007
|
} else {
|
|
987
1008
|
newNode = createValue()
|
|
988
1009
|
}
|
|
989
1010
|
|
|
990
|
-
nodes = toNodeArray(newNode)
|
|
1011
|
+
nodes = toNodeArray(newNode, ownerDocument)
|
|
991
1012
|
if (root.suspended) {
|
|
992
1013
|
handledError = true
|
|
993
1014
|
destroyRoot(root)
|
|
@@ -1048,7 +1069,7 @@ export function createChildBinding(
|
|
|
1048
1069
|
getValue: () => FictNode,
|
|
1049
1070
|
createElementFn: CreateElementFn,
|
|
1050
1071
|
): BindingHandle {
|
|
1051
|
-
const marker = document.createComment('fict:child')
|
|
1072
|
+
const marker = (parent.ownerDocument ?? document).createComment('fict:child')
|
|
1052
1073
|
parent.appendChild(marker)
|
|
1053
1074
|
const hostRoot = getCurrentRoot()
|
|
1054
1075
|
|
|
@@ -1066,7 +1087,7 @@ export function createChildBinding(
|
|
|
1066
1087
|
}
|
|
1067
1088
|
|
|
1068
1089
|
const output = createElementFn(value)
|
|
1069
|
-
nodes = toNodeArray(output)
|
|
1090
|
+
nodes = toNodeArray(output, marker.ownerDocument ?? parent.ownerDocument ?? document)
|
|
1070
1091
|
const parentNode = marker.parentNode as (ParentNode & Node) | null
|
|
1071
1092
|
if (parentNode) {
|
|
1072
1093
|
insertNodesBefore(parentNode, nodes, marker)
|
|
@@ -1244,7 +1265,7 @@ function globalEventHandler(e: Event): void {
|
|
|
1244
1265
|
Object.defineProperty(e, 'currentTarget', {
|
|
1245
1266
|
configurable: true,
|
|
1246
1267
|
get() {
|
|
1247
|
-
return node || document
|
|
1268
|
+
return node || oriCurrentTarget || asNode(oriTarget)?.ownerDocument || document
|
|
1248
1269
|
},
|
|
1249
1270
|
})
|
|
1250
1271
|
|
|
@@ -1756,14 +1777,21 @@ export function createConditional(
|
|
|
1756
1777
|
options?: ConditionalBindingOptions,
|
|
1757
1778
|
): BindingHandle {
|
|
1758
1779
|
const trackBranchReads = options?.trackBranchReads === true
|
|
1780
|
+
const hostRoot = getCurrentRoot()
|
|
1759
1781
|
const useProvided = !!(startOverride && endOverride)
|
|
1760
|
-
const
|
|
1761
|
-
|
|
1762
|
-
|
|
1782
|
+
const markerOwnerDocument =
|
|
1783
|
+
startOverride?.ownerDocument ??
|
|
1784
|
+
endOverride?.ownerDocument ??
|
|
1785
|
+
hostRoot?.ownerDocument ??
|
|
1786
|
+
document
|
|
1787
|
+
const startMarker = useProvided
|
|
1788
|
+
? startOverride!
|
|
1789
|
+
: markerOwnerDocument.createComment('fict:cond:start')
|
|
1790
|
+
const endMarker = useProvided ? endOverride! : markerOwnerDocument.createComment('fict:cond:end')
|
|
1791
|
+
const fragment = useProvided ? startMarker : markerOwnerDocument.createDocumentFragment()
|
|
1763
1792
|
if (!useProvided) {
|
|
1764
1793
|
;(fragment as DocumentFragment).append(startMarker, endMarker)
|
|
1765
1794
|
}
|
|
1766
|
-
const hostRoot = getCurrentRoot()
|
|
1767
1795
|
|
|
1768
1796
|
let currentNodes: Node[] = []
|
|
1769
1797
|
let currentRoot: RootContext | null = null
|
|
@@ -1815,7 +1843,7 @@ export function createConditional(
|
|
|
1815
1843
|
withHydrationRange(
|
|
1816
1844
|
startMarker.nextSibling,
|
|
1817
1845
|
endMarker,
|
|
1818
|
-
parent.ownerDocument ??
|
|
1846
|
+
parent.ownerDocument ?? markerOwnerDocument,
|
|
1819
1847
|
() => {
|
|
1820
1848
|
const output = trackBranchReads ? render() : untrack(render)
|
|
1821
1849
|
if (output == null || output === false) {
|
|
@@ -1921,7 +1949,7 @@ export function createConditional(
|
|
|
1921
1949
|
return
|
|
1922
1950
|
}
|
|
1923
1951
|
const el = createElementFn(scratchOutput)
|
|
1924
|
-
const nodes = toNodeArray(el)
|
|
1952
|
+
const nodes = toNodeArray(el, parent.ownerDocument ?? markerOwnerDocument)
|
|
1925
1953
|
insertNodesBefore(parent, nodes, endMarker)
|
|
1926
1954
|
currentNodes = nodes
|
|
1927
1955
|
} catch (err) {
|
|
@@ -1974,7 +2002,7 @@ export function createConditional(
|
|
|
1974
2002
|
return
|
|
1975
2003
|
}
|
|
1976
2004
|
const el = createElementFn(output)
|
|
1977
|
-
const nodes = toNodeArray(el)
|
|
2005
|
+
const nodes = toNodeArray(el, parent.ownerDocument ?? markerOwnerDocument)
|
|
1978
2006
|
insertNodesBefore(parent, nodes, endMarker)
|
|
1979
2007
|
currentNodes = nodes
|
|
1980
2008
|
} catch (err) {
|
|
@@ -2071,7 +2099,8 @@ export function createPortal(
|
|
|
2071
2099
|
// This is needed because createRenderEffect will push/pop its own root context
|
|
2072
2100
|
const parentRoot = getCurrentRoot()
|
|
2073
2101
|
|
|
2074
|
-
const
|
|
2102
|
+
const markerOwnerDocument = container.ownerDocument ?? document
|
|
2103
|
+
const marker = markerOwnerDocument.createComment('fict:portal')
|
|
2075
2104
|
container.appendChild(marker)
|
|
2076
2105
|
|
|
2077
2106
|
let currentNodes: Node[] = []
|
|
@@ -2090,13 +2119,14 @@ export function createPortal(
|
|
|
2090
2119
|
|
|
2091
2120
|
// Create new content
|
|
2092
2121
|
const root = createRootContext(parentRoot)
|
|
2122
|
+
root.ownerDocument = container.ownerDocument ?? parentRoot?.ownerDocument ?? document
|
|
2093
2123
|
const prev = pushRoot(root)
|
|
2094
2124
|
let handledError = false
|
|
2095
2125
|
try {
|
|
2096
2126
|
const output = render()
|
|
2097
2127
|
if (output != null && output !== false) {
|
|
2098
2128
|
const el = createElementFn(output)
|
|
2099
|
-
const nodes = toNodeArray(el)
|
|
2129
|
+
const nodes = toNodeArray(el, markerOwnerDocument)
|
|
2100
2130
|
if (marker.parentNode) {
|
|
2101
2131
|
insertNodesBefore(marker.parentNode as ParentNode & Node, nodes, marker)
|
|
2102
2132
|
}
|
package/src/context.ts
CHANGED
|
@@ -174,8 +174,9 @@ export function createContext<T>(defaultValue: T): Context<T> {
|
|
|
174
174
|
contextMap.set(id, props.value)
|
|
175
175
|
|
|
176
176
|
// Create DOM structure
|
|
177
|
-
const
|
|
178
|
-
const
|
|
177
|
+
const markerOwnerDocument = providerRoot.ownerDocument ?? hostRoot?.ownerDocument ?? document
|
|
178
|
+
const fragment = markerOwnerDocument.createDocumentFragment()
|
|
179
|
+
const marker = markerOwnerDocument.createComment('fict:ctx')
|
|
179
180
|
fragment.appendChild(marker)
|
|
180
181
|
|
|
181
182
|
let cleanup: (() => void) | undefined
|
|
@@ -200,7 +201,7 @@ export function createContext<T>(defaultValue: T): Context<T> {
|
|
|
200
201
|
let nodes: Node[] = []
|
|
201
202
|
try {
|
|
202
203
|
const output = createElement(children)
|
|
203
|
-
nodes = toNodeArray(output)
|
|
204
|
+
nodes = toNodeArray(output, markerOwnerDocument)
|
|
204
205
|
const parentNode = marker.parentNode as (ParentNode & Node) | null
|
|
205
206
|
if (parentNode) {
|
|
206
207
|
insertNodesBefore(parentNode, nodes, marker)
|
package/src/devtools.ts
CHANGED
|
@@ -5,18 +5,35 @@ export interface FictDevtoolsHook {
|
|
|
5
5
|
options?: { name?: string; source?: string; ownerId?: number },
|
|
6
6
|
) => void
|
|
7
7
|
updateSignal: (id: number, value: unknown) => void
|
|
8
|
+
disposeSignal?: (id: number) => void
|
|
8
9
|
registerComputed: (
|
|
9
10
|
id: number,
|
|
10
11
|
value: unknown,
|
|
11
|
-
options?: {
|
|
12
|
+
options?: {
|
|
13
|
+
name?: string
|
|
14
|
+
source?: string
|
|
15
|
+
ownerId?: number
|
|
16
|
+
hasValue?: boolean
|
|
17
|
+
internal?: boolean
|
|
18
|
+
},
|
|
12
19
|
) => void
|
|
13
20
|
updateComputed: (id: number, value: unknown) => void
|
|
21
|
+
disposeComputed?: (id: number) => void
|
|
14
22
|
registerEffect: (id: number, options?: { ownerId?: number; source?: string }) => void
|
|
15
|
-
effectRun: (id: number) => void
|
|
23
|
+
effectRun: (id: number, duration?: number) => void
|
|
24
|
+
effectCleanup?: (id: number) => void
|
|
25
|
+
disposeEffect?: (id: number) => void
|
|
16
26
|
/** Track a dependency relationship between subscriber and dependency */
|
|
17
27
|
trackDependency?: (subscriberId: number, dependencyId: number) => void
|
|
18
28
|
/** Remove a dependency relationship when unlinked */
|
|
19
29
|
untrackDependency?: (subscriberId: number, dependencyId: number) => void
|
|
30
|
+
registerRoot?: (id: number, name?: string) => void
|
|
31
|
+
disposeRoot?: (id: number) => void
|
|
32
|
+
rootSuspend?: (id: number, suspended: boolean) => void
|
|
33
|
+
batchStart?: () => void
|
|
34
|
+
batchEnd?: () => void
|
|
35
|
+
flushStart?: () => void
|
|
36
|
+
flushEnd?: () => void
|
|
20
37
|
cycleDetected?: (payload: { reason: string; detail?: Record<string, unknown> }) => void
|
|
21
38
|
|
|
22
39
|
// Component lifecycle
|