@fictjs/runtime 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- 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/{effect-DAzpH7Mm.d.cts → binding-BWchH3Kp.d.cts} +33 -24
- package/dist/{effect-DAzpH7Mm.d.ts → binding-BWchH3Kp.d.ts} +33 -24
- package/dist/{chunk-7YQK3XKY.js → chunk-DXG3TARY.js} +520 -518
- package/dist/chunk-DXG3TARY.js.map +1 -0
- package/dist/{chunk-TLDT76RV.js → chunk-FVX77557.js} +3 -3
- package/dist/{chunk-WRU3IZOA.js → chunk-JVYH76ZX.js} +3 -3
- package/dist/chunk-LBE6DC3V.cjs +768 -0
- package/dist/chunk-LBE6DC3V.cjs.map +1 -0
- package/dist/chunk-N6ODUM2Y.js +768 -0
- package/dist/chunk-N6ODUM2Y.js.map +1 -0
- package/dist/{chunk-PRF4QG73.cjs → chunk-OAM7HABA.cjs} +423 -246
- package/dist/chunk-OAM7HABA.cjs.map +1 -0
- package/dist/{chunk-CEV6TO5U.cjs → chunk-PD6IQY2Y.cjs} +8 -8
- package/dist/{chunk-CEV6TO5U.cjs.map → chunk-PD6IQY2Y.cjs.map} +1 -1
- package/dist/{chunk-HHDHQGJY.cjs → chunk-PG4QX2I2.cjs} +17 -17
- package/dist/{chunk-HHDHQGJY.cjs.map → chunk-PG4QX2I2.cjs.map} +1 -1
- package/dist/{chunk-4LCHQ7U4.js → chunk-T2LNV5Q5.js} +271 -94
- package/dist/chunk-T2LNV5Q5.js.map +1 -0
- package/dist/{chunk-FSCBL7RI.cjs → chunk-UBFDB6OL.cjs} +521 -519
- package/dist/chunk-UBFDB6OL.cjs.map +1 -0
- package/dist/{context-C4vBQbb4.d.ts → devtools-5AipK9CX.d.cts} +35 -35
- package/dist/{context-BFbHf9nC.d.cts → devtools-BDp76luf.d.ts} +35 -35
- package/dist/index.cjs +42 -42
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.dev.js +3 -3
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/internal-list.cjs +12 -0
- package/dist/internal-list.cjs.map +1 -0
- package/dist/internal-list.d.cts +2 -0
- package/dist/internal-list.d.ts +2 -0
- package/dist/internal-list.js +12 -0
- package/dist/internal-list.js.map +1 -0
- package/dist/internal.cjs +6 -746
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +6 -74
- package/dist/internal.d.ts +6 -74
- package/dist/internal.js +12 -752
- package/dist/internal.js.map +1 -1
- package/dist/list-DL5DOFcO.d.ts +71 -0
- package/dist/list-hP7hQ9Vk.d.cts +71 -0
- package/dist/loader.cjs +94 -15
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.d.cts +16 -2
- package/dist/loader.d.ts +16 -2
- package/dist/loader.js +87 -8
- package/dist/loader.js.map +1 -1
- package/dist/{props-84UJeWO8.d.cts → props-BpZz0AOq.d.cts} +2 -2
- package/dist/{props-BRhFK50f.d.ts → props-CjLH0JE-.d.ts} +2 -2
- package/dist/{resume-i-A3EFox.d.cts → resume-BJ4oHLi_.d.cts} +3 -1
- package/dist/{resume-CqeQ3v_q.d.ts → resume-CuyJWXP_.d.ts} +3 -1
- package/dist/{scope-DlCBL1Ft.d.cts → scope-BJCtq8hJ.d.cts} +1 -1
- package/dist/{scope-D3DpsfoG.d.ts → scope-jPt5DHRT.d.ts} +1 -1
- package/package.json +8 -1
- package/src/binding.ts +113 -36
- package/src/cycle-guard.ts +3 -3
- package/src/internal/list.ts +7 -0
- package/src/internal.ts +1 -0
- package/src/list-helpers.ts +1 -1
- package/src/loader.ts +119 -9
- package/src/resume.ts +6 -3
- package/src/signal.ts +8 -1
- package/dist/chunk-4LCHQ7U4.js.map +0 -1
- package/dist/chunk-7YQK3XKY.js.map +0 -1
- package/dist/chunk-FSCBL7RI.cjs.map +0 -1
- package/dist/chunk-PRF4QG73.cjs.map +0 -1
- /package/dist/{chunk-TLDT76RV.js.map → chunk-FVX77557.js.map} +0 -0
- /package/dist/{chunk-WRU3IZOA.js.map → chunk-JVYH76ZX.js.map} +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkOAM7HABAcjs = require('./chunk-OAM7HABA.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -12,7 +12,7 @@ var _chunkPRF4QG73cjs = require('./chunk-PRF4QG73.cjs');
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
var
|
|
15
|
+
var _chunkUBFDB6OLcjs = require('./chunk-UBFDB6OL.cjs');
|
|
16
16
|
|
|
17
17
|
// src/context.ts
|
|
18
18
|
var contextStorage = /* @__PURE__ */ new WeakMap();
|
|
@@ -32,8 +32,8 @@ function createContext(defaultValue) {
|
|
|
32
32
|
Provider: null
|
|
33
33
|
};
|
|
34
34
|
context.Provider = function Provider(props) {
|
|
35
|
-
const hostRoot =
|
|
36
|
-
const providerRoot =
|
|
35
|
+
const hostRoot = _chunkUBFDB6OLcjs.getCurrentRoot.call(void 0, );
|
|
36
|
+
const providerRoot = _chunkUBFDB6OLcjs.createRootContext.call(void 0, hostRoot);
|
|
37
37
|
const contextMap = getContextMap(providerRoot);
|
|
38
38
|
contextMap.set(id, props.value);
|
|
39
39
|
const fragment = document.createDocumentFragment();
|
|
@@ -47,32 +47,32 @@ function createContext(defaultValue) {
|
|
|
47
47
|
cleanup = void 0;
|
|
48
48
|
}
|
|
49
49
|
if (activeNodes.length) {
|
|
50
|
-
|
|
50
|
+
_chunkOAM7HABAcjs.removeNodes.call(void 0, activeNodes);
|
|
51
51
|
activeNodes = [];
|
|
52
52
|
}
|
|
53
53
|
if (children == null || children === false) {
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
|
-
const prev =
|
|
56
|
+
const prev = _chunkUBFDB6OLcjs.pushRoot.call(void 0, providerRoot);
|
|
57
57
|
let nodes = [];
|
|
58
58
|
try {
|
|
59
|
-
const output =
|
|
60
|
-
nodes =
|
|
59
|
+
const output = _chunkOAM7HABAcjs.createElement.call(void 0, children);
|
|
60
|
+
nodes = _chunkOAM7HABAcjs.toNodeArray.call(void 0, output);
|
|
61
61
|
const parentNode = marker.parentNode;
|
|
62
62
|
if (parentNode) {
|
|
63
|
-
|
|
63
|
+
_chunkOAM7HABAcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
|
|
64
64
|
}
|
|
65
65
|
} finally {
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
_chunkUBFDB6OLcjs.popRoot.call(void 0, prev);
|
|
67
|
+
_chunkUBFDB6OLcjs.flushOnMount.call(void 0, providerRoot);
|
|
68
68
|
}
|
|
69
69
|
cleanup = () => {
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
_chunkUBFDB6OLcjs.destroyRoot.call(void 0, providerRoot);
|
|
71
|
+
_chunkOAM7HABAcjs.removeNodes.call(void 0, nodes);
|
|
72
72
|
};
|
|
73
73
|
activeNodes = nodes;
|
|
74
74
|
};
|
|
75
|
-
|
|
75
|
+
_chunkUBFDB6OLcjs.createRenderEffect.call(void 0, () => {
|
|
76
76
|
contextMap.set(id, props.value);
|
|
77
77
|
renderChildren(props.children);
|
|
78
78
|
});
|
|
@@ -81,7 +81,7 @@ function createContext(defaultValue) {
|
|
|
81
81
|
return context;
|
|
82
82
|
}
|
|
83
83
|
function useContext(context) {
|
|
84
|
-
let root =
|
|
84
|
+
let root = _chunkUBFDB6OLcjs.getCurrentRoot.call(void 0, );
|
|
85
85
|
while (root) {
|
|
86
86
|
const contextMap = contextStorage.get(root);
|
|
87
87
|
if (contextMap && contextMap.has(context.id)) {
|
|
@@ -92,7 +92,7 @@ function useContext(context) {
|
|
|
92
92
|
return context.defaultValue;
|
|
93
93
|
}
|
|
94
94
|
function hasContext(context) {
|
|
95
|
-
let root =
|
|
95
|
+
let root = _chunkUBFDB6OLcjs.getCurrentRoot.call(void 0, );
|
|
96
96
|
while (root) {
|
|
97
97
|
const contextMap = contextStorage.get(root);
|
|
98
98
|
if (contextMap && contextMap.has(context.id)) {
|
|
@@ -108,4 +108,4 @@ function hasContext(context) {
|
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
exports.createContext = createContext; exports.useContext = useContext; exports.hasContext = hasContext;
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-PG4QX2I2.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/chunk-HHDHQGJY.cjs","../src/context.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fict/fict/packages/runtime/dist/chunk-HHDHQGJY.cjs","sourcesContent":[null,"/**\n * @fileoverview Context API for Fict\n *\n * Provides a way to pass data through the component tree without having to pass\n * props down manually at every level. Context is designed for:\n *\n * - SSR isolation (different request = different context values)\n * - Multi-instance support (multiple app roots with different values)\n * - Subtree scoping (override values in specific parts of the tree)\n *\n * ## Design Principles\n *\n * 1. **Reuses existing RootContext hierarchy** - Uses parent chain for value lookup,\n * consistent with handleError/handleSuspend mechanisms.\n *\n * 2. **Zero extra root creation overhead** - Provider doesn't create new root,\n * only mounts value on current root.\n *\n * 3. **Auto-aligned with insert/suspense boundaries** - Because they create child\n * roots that inherit parent, context values propagate correctly.\n *\n * ## Usage\n *\n * ```tsx\n * // Create context with default value\n * const ThemeContext = createContext<'light' | 'dark'>('light')\n *\n * // Provide value to subtree\n * function App() {\n * return (\n * <ThemeContext.Provider value=\"dark\">\n * <ThemedComponent />\n * </ThemeContext.Provider>\n * )\n * }\n *\n * // Consume value\n * function ThemedComponent() {\n * const theme = useContext(ThemeContext)\n * return <div class={theme}>...</div>\n * }\n * ```\n *\n * @module\n */\n\nimport { createElement } from './dom'\nimport { createRenderEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n popRoot,\n pushRoot,\n type RootContext,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport type { BaseProps, FictNode } from './types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Context object created by createContext.\n * Contains the Provider component and serves as a key for context lookup.\n */\nexport interface Context<T> {\n /** Unique identifier for this context */\n readonly id: symbol\n /** Default value when no provider is found */\n readonly defaultValue: T\n /** Provider component for supplying context values */\n Provider: ContextProvider<T>\n /** Display name for debugging */\n displayName?: string\n}\n\n/**\n * Props for the Context Provider component\n */\nexport interface ProviderProps<T> extends BaseProps {\n /** The value to provide to the subtree */\n value: T\n}\n\n/**\n * Provider component type\n */\nexport type ContextProvider<T> = (props: ProviderProps<T>) => FictNode\n\n// ============================================================================\n// Internal Context Storage\n// ============================================================================\n\n/**\n * WeakMap to store context values per RootContext.\n * Using WeakMap ensures proper garbage collection when roots are destroyed.\n */\nconst contextStorage = new WeakMap<RootContext, Map<symbol, unknown>>()\n\n/**\n * Get the context map for a root, creating it if needed\n */\nfunction getContextMap(root: RootContext): Map<symbol, unknown> {\n let map = contextStorage.get(root)\n if (!map) {\n map = new Map()\n contextStorage.set(root, map)\n }\n return map\n}\n\n// ============================================================================\n// Context API\n// ============================================================================\n\n/**\n * Creates a new context with the given default value.\n *\n * Context provides a way to pass values through the component tree without\n * explicit props drilling. It's especially useful for:\n *\n * - Theme data\n * - Locale/i18n settings\n * - Authentication state\n * - Feature flags\n * - Any data that many components at different nesting levels need\n *\n * @param defaultValue - The value to use when no Provider is found above in the tree\n * @returns A context object with a Provider component\n *\n * @example\n * ```tsx\n * // Create a theme context\n * const ThemeContext = createContext<'light' | 'dark'>('light')\n *\n * // Use the provider\n * function App() {\n * return (\n * <ThemeContext.Provider value=\"dark\">\n * <Content />\n * </ThemeContext.Provider>\n * )\n * }\n *\n * // Consume the context\n * function Content() {\n * const theme = useContext(ThemeContext)\n * return <div class={`theme-${theme}`}>Hello</div>\n * }\n * ```\n */\nexport function createContext<T>(defaultValue: T): Context<T> {\n const id = Symbol('fict.context')\n\n const context: Context<T> = {\n id,\n defaultValue,\n Provider: null as unknown as ContextProvider<T>,\n }\n\n // Create the Provider component\n context.Provider = function Provider(props: ProviderProps<T>): FictNode {\n const hostRoot = getCurrentRoot()\n\n // Create a child root for the provider's subtree\n // This establishes the provider boundary - children will look up from here\n const providerRoot = createRootContext(hostRoot)\n\n // Store the context value on this root\n const contextMap = getContextMap(providerRoot)\n contextMap.set(id, props.value)\n\n // Create DOM structure\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:ctx')\n fragment.appendChild(marker)\n\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n\n const renderChildren = (children: FictNode) => {\n // Cleanup previous render\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (children == null || children === false) {\n return\n }\n\n const prev = pushRoot(providerRoot)\n let nodes: Node[] = []\n try {\n const output = createElement(children)\n nodes = toNodeArray(output)\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } finally {\n popRoot(prev)\n flushOnMount(providerRoot)\n }\n\n cleanup = () => {\n destroyRoot(providerRoot)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n // Initial render\n createRenderEffect(() => {\n // Update context value on re-render (if value prop changes reactively)\n contextMap.set(id, props.value)\n renderChildren(props.children)\n })\n\n return fragment\n }\n\n return context\n}\n\n/**\n * Reads the current value of a context.\n *\n * useContext looks up through the RootContext parent chain to find the\n * nearest Provider for this context. If no Provider is found, returns\n * the context's default value.\n *\n * @param context - The context object created by createContext\n * @returns The current context value\n *\n * @example\n * ```tsx\n * const ThemeContext = createContext('light')\n *\n * function ThemedButton() {\n * const theme = useContext(ThemeContext)\n * return <button class={theme === 'dark' ? 'btn-dark' : 'btn-light'}>Click</button>\n * }\n * ```\n */\nexport function useContext<T>(context: Context<T>): T {\n let root = getCurrentRoot()\n\n // Walk up the parent chain looking for the context value\n while (root) {\n const contextMap = contextStorage.get(root)\n if (contextMap && contextMap.has(context.id)) {\n return contextMap.get(context.id) as T\n }\n root = root.parent\n }\n\n // No provider found, return default value\n return context.defaultValue\n}\n\n/**\n * Checks if a context value is currently provided in the tree.\n *\n * Useful for conditional behavior when a provider may or may not exist.\n *\n * @param context - The context object to check\n * @returns true if a Provider exists above in the tree\n *\n * @example\n * ```tsx\n * function OptionalTheme() {\n * if (hasContext(ThemeContext)) {\n * const theme = useContext(ThemeContext)\n * return <div class={theme}>Themed content</div>\n * }\n * return <div>Default content</div>\n * }\n * ```\n */\nexport function hasContext<T>(context: Context<T>): boolean {\n let root = getCurrentRoot()\n\n while (root) {\n const contextMap = contextStorage.get(root)\n if (contextMap && contextMap.has(context.id)) {\n return true\n }\n root = root.parent\n }\n\n return false\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/chunk-PG4QX2I2.cjs","../src/context.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fict/fict/packages/runtime/dist/chunk-PG4QX2I2.cjs","sourcesContent":[null,"/**\n * @fileoverview Context API for Fict\n *\n * Provides a way to pass data through the component tree without having to pass\n * props down manually at every level. Context is designed for:\n *\n * - SSR isolation (different request = different context values)\n * - Multi-instance support (multiple app roots with different values)\n * - Subtree scoping (override values in specific parts of the tree)\n *\n * ## Design Principles\n *\n * 1. **Reuses existing RootContext hierarchy** - Uses parent chain for value lookup,\n * consistent with handleError/handleSuspend mechanisms.\n *\n * 2. **Zero extra root creation overhead** - Provider doesn't create new root,\n * only mounts value on current root.\n *\n * 3. **Auto-aligned with insert/suspense boundaries** - Because they create child\n * roots that inherit parent, context values propagate correctly.\n *\n * ## Usage\n *\n * ```tsx\n * // Create context with default value\n * const ThemeContext = createContext<'light' | 'dark'>('light')\n *\n * // Provide value to subtree\n * function App() {\n * return (\n * <ThemeContext.Provider value=\"dark\">\n * <ThemedComponent />\n * </ThemeContext.Provider>\n * )\n * }\n *\n * // Consume value\n * function ThemedComponent() {\n * const theme = useContext(ThemeContext)\n * return <div class={theme}>...</div>\n * }\n * ```\n *\n * @module\n */\n\nimport { createElement } from './dom'\nimport { createRenderEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n popRoot,\n pushRoot,\n type RootContext,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport type { BaseProps, FictNode } from './types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Context object created by createContext.\n * Contains the Provider component and serves as a key for context lookup.\n */\nexport interface Context<T> {\n /** Unique identifier for this context */\n readonly id: symbol\n /** Default value when no provider is found */\n readonly defaultValue: T\n /** Provider component for supplying context values */\n Provider: ContextProvider<T>\n /** Display name for debugging */\n displayName?: string\n}\n\n/**\n * Props for the Context Provider component\n */\nexport interface ProviderProps<T> extends BaseProps {\n /** The value to provide to the subtree */\n value: T\n}\n\n/**\n * Provider component type\n */\nexport type ContextProvider<T> = (props: ProviderProps<T>) => FictNode\n\n// ============================================================================\n// Internal Context Storage\n// ============================================================================\n\n/**\n * WeakMap to store context values per RootContext.\n * Using WeakMap ensures proper garbage collection when roots are destroyed.\n */\nconst contextStorage = new WeakMap<RootContext, Map<symbol, unknown>>()\n\n/**\n * Get the context map for a root, creating it if needed\n */\nfunction getContextMap(root: RootContext): Map<symbol, unknown> {\n let map = contextStorage.get(root)\n if (!map) {\n map = new Map()\n contextStorage.set(root, map)\n }\n return map\n}\n\n// ============================================================================\n// Context API\n// ============================================================================\n\n/**\n * Creates a new context with the given default value.\n *\n * Context provides a way to pass values through the component tree without\n * explicit props drilling. It's especially useful for:\n *\n * - Theme data\n * - Locale/i18n settings\n * - Authentication state\n * - Feature flags\n * - Any data that many components at different nesting levels need\n *\n * @param defaultValue - The value to use when no Provider is found above in the tree\n * @returns A context object with a Provider component\n *\n * @example\n * ```tsx\n * // Create a theme context\n * const ThemeContext = createContext<'light' | 'dark'>('light')\n *\n * // Use the provider\n * function App() {\n * return (\n * <ThemeContext.Provider value=\"dark\">\n * <Content />\n * </ThemeContext.Provider>\n * )\n * }\n *\n * // Consume the context\n * function Content() {\n * const theme = useContext(ThemeContext)\n * return <div class={`theme-${theme}`}>Hello</div>\n * }\n * ```\n */\nexport function createContext<T>(defaultValue: T): Context<T> {\n const id = Symbol('fict.context')\n\n const context: Context<T> = {\n id,\n defaultValue,\n Provider: null as unknown as ContextProvider<T>,\n }\n\n // Create the Provider component\n context.Provider = function Provider(props: ProviderProps<T>): FictNode {\n const hostRoot = getCurrentRoot()\n\n // Create a child root for the provider's subtree\n // This establishes the provider boundary - children will look up from here\n const providerRoot = createRootContext(hostRoot)\n\n // Store the context value on this root\n const contextMap = getContextMap(providerRoot)\n contextMap.set(id, props.value)\n\n // Create DOM structure\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:ctx')\n fragment.appendChild(marker)\n\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n\n const renderChildren = (children: FictNode) => {\n // Cleanup previous render\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (children == null || children === false) {\n return\n }\n\n const prev = pushRoot(providerRoot)\n let nodes: Node[] = []\n try {\n const output = createElement(children)\n nodes = toNodeArray(output)\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } finally {\n popRoot(prev)\n flushOnMount(providerRoot)\n }\n\n cleanup = () => {\n destroyRoot(providerRoot)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n // Initial render\n createRenderEffect(() => {\n // Update context value on re-render (if value prop changes reactively)\n contextMap.set(id, props.value)\n renderChildren(props.children)\n })\n\n return fragment\n }\n\n return context\n}\n\n/**\n * Reads the current value of a context.\n *\n * useContext looks up through the RootContext parent chain to find the\n * nearest Provider for this context. If no Provider is found, returns\n * the context's default value.\n *\n * @param context - The context object created by createContext\n * @returns The current context value\n *\n * @example\n * ```tsx\n * const ThemeContext = createContext('light')\n *\n * function ThemedButton() {\n * const theme = useContext(ThemeContext)\n * return <button class={theme === 'dark' ? 'btn-dark' : 'btn-light'}>Click</button>\n * }\n * ```\n */\nexport function useContext<T>(context: Context<T>): T {\n let root = getCurrentRoot()\n\n // Walk up the parent chain looking for the context value\n while (root) {\n const contextMap = contextStorage.get(root)\n if (contextMap && contextMap.has(context.id)) {\n return contextMap.get(context.id) as T\n }\n root = root.parent\n }\n\n // No provider found, return default value\n return context.defaultValue\n}\n\n/**\n * Checks if a context value is currently provided in the tree.\n *\n * Useful for conditional behavior when a provider may or may not exist.\n *\n * @param context - The context object to check\n * @returns true if a Provider exists above in the tree\n *\n * @example\n * ```tsx\n * function OptionalTheme() {\n * if (hasContext(ThemeContext)) {\n * const theme = useContext(ThemeContext)\n * return <div class={theme}>Themed content</div>\n * }\n * return <div>Default content</div>\n * }\n * ```\n */\nexport function hasContext<T>(context: Context<T>): boolean {\n let root = getCurrentRoot()\n\n while (root) {\n const contextMap = contextStorage.get(root)\n if (contextMap && contextMap.has(context.id)) {\n return true\n }\n root = root.parent\n }\n\n return false\n}\n"]}
|
|
@@ -40,7 +40,86 @@ import {
|
|
|
40
40
|
setTransitionContext,
|
|
41
41
|
signal,
|
|
42
42
|
untrack
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-DXG3TARY.js";
|
|
44
|
+
|
|
45
|
+
// src/transition.ts
|
|
46
|
+
function startTransition(fn) {
|
|
47
|
+
const prev = setTransitionContext(true);
|
|
48
|
+
try {
|
|
49
|
+
fn();
|
|
50
|
+
} finally {
|
|
51
|
+
setTransitionContext(prev);
|
|
52
|
+
scheduleFlush();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function useTransition() {
|
|
56
|
+
const pending = signal(false);
|
|
57
|
+
let pendingCount = 0;
|
|
58
|
+
const beginPending = () => {
|
|
59
|
+
pendingCount += 1;
|
|
60
|
+
if (pendingCount === 1) {
|
|
61
|
+
pending(true);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const endPending = () => {
|
|
65
|
+
if (pendingCount === 0) return;
|
|
66
|
+
pendingCount -= 1;
|
|
67
|
+
if (pendingCount === 0) {
|
|
68
|
+
pending(false);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const start = (fn) => {
|
|
72
|
+
beginPending();
|
|
73
|
+
let result;
|
|
74
|
+
let thrown;
|
|
75
|
+
let didThrow = false;
|
|
76
|
+
startTransition(() => {
|
|
77
|
+
try {
|
|
78
|
+
result = fn();
|
|
79
|
+
} catch (err) {
|
|
80
|
+
thrown = err;
|
|
81
|
+
didThrow = true;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
if (didThrow) {
|
|
85
|
+
endPending();
|
|
86
|
+
throw thrown;
|
|
87
|
+
}
|
|
88
|
+
if (result && typeof result.then === "function") {
|
|
89
|
+
Promise.resolve(result).finally(() => {
|
|
90
|
+
endPending();
|
|
91
|
+
});
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (typeof queueMicrotask === "function") {
|
|
95
|
+
queueMicrotask(endPending);
|
|
96
|
+
} else {
|
|
97
|
+
Promise.resolve().then(endPending);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
return [() => pending(), start];
|
|
101
|
+
}
|
|
102
|
+
function useDeferredValue(getValue) {
|
|
103
|
+
const deferredValue = signal(getValue());
|
|
104
|
+
createEffect(() => {
|
|
105
|
+
const newValue = getValue();
|
|
106
|
+
const currentDeferred = untrack(() => deferredValue());
|
|
107
|
+
if (currentDeferred !== newValue) {
|
|
108
|
+
startTransition(() => {
|
|
109
|
+
deferredValue(newValue);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
return () => deferredValue();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/scheduler.ts
|
|
117
|
+
function batch2(fn) {
|
|
118
|
+
return batch(fn);
|
|
119
|
+
}
|
|
120
|
+
function untrack2(fn) {
|
|
121
|
+
return untrack(fn);
|
|
122
|
+
}
|
|
44
123
|
|
|
45
124
|
// src/jsx.ts
|
|
46
125
|
var Fragment = Symbol("Fragment");
|
|
@@ -247,85 +326,6 @@ function resolvePath(root, path) {
|
|
|
247
326
|
return current;
|
|
248
327
|
}
|
|
249
328
|
|
|
250
|
-
// src/transition.ts
|
|
251
|
-
function startTransition(fn) {
|
|
252
|
-
const prev = setTransitionContext(true);
|
|
253
|
-
try {
|
|
254
|
-
fn();
|
|
255
|
-
} finally {
|
|
256
|
-
setTransitionContext(prev);
|
|
257
|
-
scheduleFlush();
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
function useTransition() {
|
|
261
|
-
const pending = signal(false);
|
|
262
|
-
let pendingCount = 0;
|
|
263
|
-
const beginPending = () => {
|
|
264
|
-
pendingCount += 1;
|
|
265
|
-
if (pendingCount === 1) {
|
|
266
|
-
pending(true);
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
const endPending = () => {
|
|
270
|
-
if (pendingCount === 0) return;
|
|
271
|
-
pendingCount -= 1;
|
|
272
|
-
if (pendingCount === 0) {
|
|
273
|
-
pending(false);
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
const start = (fn) => {
|
|
277
|
-
beginPending();
|
|
278
|
-
let result;
|
|
279
|
-
let thrown;
|
|
280
|
-
let didThrow = false;
|
|
281
|
-
startTransition(() => {
|
|
282
|
-
try {
|
|
283
|
-
result = fn();
|
|
284
|
-
} catch (err) {
|
|
285
|
-
thrown = err;
|
|
286
|
-
didThrow = true;
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
if (didThrow) {
|
|
290
|
-
endPending();
|
|
291
|
-
throw thrown;
|
|
292
|
-
}
|
|
293
|
-
if (result && typeof result.then === "function") {
|
|
294
|
-
Promise.resolve(result).finally(() => {
|
|
295
|
-
endPending();
|
|
296
|
-
});
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
if (typeof queueMicrotask === "function") {
|
|
300
|
-
queueMicrotask(endPending);
|
|
301
|
-
} else {
|
|
302
|
-
Promise.resolve().then(endPending);
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
return [() => pending(), start];
|
|
306
|
-
}
|
|
307
|
-
function useDeferredValue(getValue) {
|
|
308
|
-
const deferredValue = signal(getValue());
|
|
309
|
-
createEffect(() => {
|
|
310
|
-
const newValue = getValue();
|
|
311
|
-
const currentDeferred = untrack(() => deferredValue());
|
|
312
|
-
if (currentDeferred !== newValue) {
|
|
313
|
-
startTransition(() => {
|
|
314
|
-
deferredValue(newValue);
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
return () => deferredValue();
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// src/scheduler.ts
|
|
322
|
-
function batch2(fn) {
|
|
323
|
-
return batch(fn);
|
|
324
|
-
}
|
|
325
|
-
function untrack2(fn) {
|
|
326
|
-
return untrack(fn);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
329
|
// src/hydration.ts
|
|
330
330
|
var hydrationStack = [];
|
|
331
331
|
function withHydration(root, fn) {
|
|
@@ -1375,7 +1375,8 @@ function assignProp(node, prop2, value, prev, isSVG, skipRef, props) {
|
|
|
1375
1375
|
function toPropertyName(name) {
|
|
1376
1376
|
return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase());
|
|
1377
1377
|
}
|
|
1378
|
-
function createConditional(condition, renderTrue, createElementFn, renderFalse, startOverride, endOverride) {
|
|
1378
|
+
function createConditional(condition, renderTrue, createElementFn, renderFalse, startOverride, endOverride, options) {
|
|
1379
|
+
const trackBranchReads = options?.trackBranchReads === true;
|
|
1379
1380
|
const useProvided = !!(startOverride && endOverride);
|
|
1380
1381
|
const startMarker = useProvided ? startOverride : document.createComment("fict:cond:start");
|
|
1381
1382
|
const endMarker = useProvided ? endOverride : document.createComment("fict:cond:end");
|
|
@@ -1425,7 +1426,7 @@ function createConditional(condition, renderTrue, createElementFn, renderFalse,
|
|
|
1425
1426
|
endMarker,
|
|
1426
1427
|
parent.ownerDocument ?? document,
|
|
1427
1428
|
() => {
|
|
1428
|
-
const output = untrack(render3);
|
|
1429
|
+
const output = trackBranchReads ? render3() : untrack(render3);
|
|
1429
1430
|
if (output == null || output === false) {
|
|
1430
1431
|
return;
|
|
1431
1432
|
}
|
|
@@ -1456,10 +1457,96 @@ function createConditional(condition, renderTrue, createElementFn, renderFalse,
|
|
|
1456
1457
|
}
|
|
1457
1458
|
return;
|
|
1458
1459
|
}
|
|
1459
|
-
if (
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1460
|
+
if (!trackBranchReads) {
|
|
1461
|
+
if (lastCondition === cond && currentNodes.length > 0) {
|
|
1462
|
+
return;
|
|
1463
|
+
}
|
|
1464
|
+
if (lastCondition === cond && lastCondition === false && renderFalse === void 0) {
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1467
|
+
} else if (lastCondition === cond) {
|
|
1468
|
+
const render3 = cond ? renderTrue : renderFalse;
|
|
1469
|
+
if (!render3) {
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
let patched = false;
|
|
1473
|
+
const scratchRoot = createRootContext(hostRoot);
|
|
1474
|
+
const prevScratch = pushRoot(scratchRoot);
|
|
1475
|
+
let handledPatchError = false;
|
|
1476
|
+
let scratchOutput = null;
|
|
1477
|
+
try {
|
|
1478
|
+
const output = render3();
|
|
1479
|
+
scratchOutput = output;
|
|
1480
|
+
if (output != null && output !== false) {
|
|
1481
|
+
if (currentNodes.length === 1) {
|
|
1482
|
+
patched = patchNode(currentNodes[0] ?? null, output);
|
|
1483
|
+
}
|
|
1484
|
+
if (!patched && Array.isArray(output)) {
|
|
1485
|
+
patched = _patchFragmentChildren(currentNodes, output);
|
|
1486
|
+
}
|
|
1487
|
+
if (!patched && _isFragmentVNode(output)) {
|
|
1488
|
+
patched = _patchFragmentChildren(currentNodes, output.props?.children);
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
} catch (err) {
|
|
1492
|
+
if (handleSuspend(err, scratchRoot)) {
|
|
1493
|
+
handledPatchError = true;
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
if (handleError(err, { source: "renderChild" }, scratchRoot)) {
|
|
1497
|
+
handledPatchError = true;
|
|
1498
|
+
return;
|
|
1499
|
+
}
|
|
1500
|
+
throw err;
|
|
1501
|
+
} finally {
|
|
1502
|
+
popRoot(prevScratch);
|
|
1503
|
+
}
|
|
1504
|
+
if (handledPatchError) {
|
|
1505
|
+
destroyRoot(scratchRoot);
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
if (patched) {
|
|
1509
|
+
destroyRoot(scratchRoot);
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
lastCondition = cond;
|
|
1513
|
+
if (currentRoot) {
|
|
1514
|
+
destroyRoot(currentRoot);
|
|
1515
|
+
currentRoot = null;
|
|
1516
|
+
}
|
|
1517
|
+
removeNodes(currentNodes);
|
|
1518
|
+
currentNodes = [];
|
|
1519
|
+
const prev2 = pushRoot(scratchRoot);
|
|
1520
|
+
let handledError2 = false;
|
|
1521
|
+
try {
|
|
1522
|
+
if (scratchOutput == null || scratchOutput === false) {
|
|
1523
|
+
return;
|
|
1524
|
+
}
|
|
1525
|
+
const el = createElementFn(scratchOutput);
|
|
1526
|
+
const nodes = toNodeArray(el);
|
|
1527
|
+
insertNodesBefore(parent, nodes, endMarker);
|
|
1528
|
+
currentNodes = nodes;
|
|
1529
|
+
} catch (err) {
|
|
1530
|
+
if (handleSuspend(err, scratchRoot)) {
|
|
1531
|
+
handledError2 = true;
|
|
1532
|
+
destroyRoot(scratchRoot);
|
|
1533
|
+
return;
|
|
1534
|
+
}
|
|
1535
|
+
if (handleError(err, { source: "renderChild" }, scratchRoot)) {
|
|
1536
|
+
handledError2 = true;
|
|
1537
|
+
destroyRoot(scratchRoot);
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
throw err;
|
|
1541
|
+
} finally {
|
|
1542
|
+
popRoot(prev2);
|
|
1543
|
+
if (!handledError2) {
|
|
1544
|
+
flushOnMount(scratchRoot);
|
|
1545
|
+
currentRoot = scratchRoot;
|
|
1546
|
+
} else {
|
|
1547
|
+
currentRoot = null;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1463
1550
|
return;
|
|
1464
1551
|
}
|
|
1465
1552
|
lastCondition = cond;
|
|
@@ -1477,7 +1564,7 @@ function createConditional(condition, renderTrue, createElementFn, renderFalse,
|
|
|
1477
1564
|
const prev = pushRoot(root);
|
|
1478
1565
|
let handledError = false;
|
|
1479
1566
|
try {
|
|
1480
|
-
const output = untrack(render2);
|
|
1567
|
+
const output = trackBranchReads ? render2() : untrack(render2);
|
|
1481
1568
|
if (output == null || output === false) {
|
|
1482
1569
|
return;
|
|
1483
1570
|
}
|
|
@@ -1603,6 +1690,96 @@ function createPortal(container, render2, createElementFn) {
|
|
|
1603
1690
|
dispose: portalDispose
|
|
1604
1691
|
};
|
|
1605
1692
|
}
|
|
1693
|
+
function patchElement(el, output) {
|
|
1694
|
+
if (output && typeof output === "object" && !(output instanceof Node)) {
|
|
1695
|
+
const vnode = output;
|
|
1696
|
+
if (typeof vnode.type === "string" && vnode.type.toLowerCase() === el.tagName.toLowerCase()) {
|
|
1697
|
+
const children = vnode.props?.children;
|
|
1698
|
+
const props = vnode.props ?? {};
|
|
1699
|
+
for (const [key, value] of Object.entries(props)) {
|
|
1700
|
+
if (key === "children" || key === "key") continue;
|
|
1701
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null || value === void 0) {
|
|
1702
|
+
if (key === "class" || key === "className") {
|
|
1703
|
+
el.setAttribute("class", value === false || value === null ? "" : String(value));
|
|
1704
|
+
} else if (key === "style" && typeof value === "string") {
|
|
1705
|
+
;
|
|
1706
|
+
el.style.cssText = value;
|
|
1707
|
+
} else if (value === false || value === null || value === void 0) {
|
|
1708
|
+
el.removeAttribute(key);
|
|
1709
|
+
} else if (value === true) {
|
|
1710
|
+
el.setAttribute(key, "");
|
|
1711
|
+
} else {
|
|
1712
|
+
el.setAttribute(key, String(value));
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
if (typeof children === "string" || typeof children === "number" || children === null || children === void 0 || children === false) {
|
|
1717
|
+
el.textContent = children === null || children === void 0 || children === false ? "" : String(children);
|
|
1718
|
+
return true;
|
|
1719
|
+
}
|
|
1720
|
+
if (children && typeof children === "object" && !Array.isArray(children) && !(children instanceof Node)) {
|
|
1721
|
+
const childVNode = children;
|
|
1722
|
+
if (typeof childVNode.type === "string") {
|
|
1723
|
+
const childEl = el.querySelector(childVNode.type);
|
|
1724
|
+
if (childEl && patchElement(childEl, children)) {
|
|
1725
|
+
return true;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
return false;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
return false;
|
|
1733
|
+
}
|
|
1734
|
+
function patchNode(currentNode, nextOutput) {
|
|
1735
|
+
if (!currentNode) return false;
|
|
1736
|
+
if (currentNode instanceof Text && (nextOutput === null || nextOutput === void 0 || nextOutput === false || typeof nextOutput === "string" || typeof nextOutput === "number" || nextOutput instanceof Text)) {
|
|
1737
|
+
const nextText = nextOutput instanceof Text ? nextOutput.data : nextOutput === null || nextOutput === void 0 || nextOutput === false ? "" : String(nextOutput);
|
|
1738
|
+
currentNode.data = nextText;
|
|
1739
|
+
return true;
|
|
1740
|
+
}
|
|
1741
|
+
if (currentNode instanceof Element && patchElement(currentNode, nextOutput)) {
|
|
1742
|
+
return true;
|
|
1743
|
+
}
|
|
1744
|
+
if (nextOutput instanceof Node && currentNode === nextOutput) {
|
|
1745
|
+
return true;
|
|
1746
|
+
}
|
|
1747
|
+
return false;
|
|
1748
|
+
}
|
|
1749
|
+
function _isFragmentVNode(value) {
|
|
1750
|
+
return value != null && typeof value === "object" && !(value instanceof Node) && value.type === Fragment;
|
|
1751
|
+
}
|
|
1752
|
+
function normalizeChildren(children, result = []) {
|
|
1753
|
+
if (children === void 0) {
|
|
1754
|
+
return result;
|
|
1755
|
+
}
|
|
1756
|
+
if (Array.isArray(children)) {
|
|
1757
|
+
for (const child of children) {
|
|
1758
|
+
normalizeChildren(child, result);
|
|
1759
|
+
}
|
|
1760
|
+
return result;
|
|
1761
|
+
}
|
|
1762
|
+
if (children === null || children === false) {
|
|
1763
|
+
return result;
|
|
1764
|
+
}
|
|
1765
|
+
if (_isFragmentVNode(children)) {
|
|
1766
|
+
return normalizeChildren(children.props?.children, result);
|
|
1767
|
+
}
|
|
1768
|
+
result.push(children);
|
|
1769
|
+
return result;
|
|
1770
|
+
}
|
|
1771
|
+
function _patchFragmentChildren(nodes, children) {
|
|
1772
|
+
const normalized = normalizeChildren(children);
|
|
1773
|
+
if (normalized.length !== nodes.length) {
|
|
1774
|
+
return false;
|
|
1775
|
+
}
|
|
1776
|
+
for (let i = 0; i < normalized.length; i++) {
|
|
1777
|
+
if (!patchNode(nodes[i], normalized[i])) {
|
|
1778
|
+
return false;
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
return true;
|
|
1782
|
+
}
|
|
1606
1783
|
|
|
1607
1784
|
// src/props.ts
|
|
1608
1785
|
var PROP_GETTER_MARKER2 = Symbol.for("fict:prop-getter");
|
|
@@ -2350,19 +2527,19 @@ function eventNameFromProp(key) {
|
|
|
2350
2527
|
}
|
|
2351
2528
|
|
|
2352
2529
|
export {
|
|
2530
|
+
startTransition,
|
|
2531
|
+
useTransition,
|
|
2532
|
+
useDeferredValue,
|
|
2533
|
+
batch2 as batch,
|
|
2534
|
+
untrack2 as untrack,
|
|
2535
|
+
Fragment,
|
|
2353
2536
|
withHydrationRange,
|
|
2354
2537
|
isHydratingActive,
|
|
2355
|
-
Fragment,
|
|
2356
2538
|
toNodeArray,
|
|
2357
2539
|
insertNodesBefore,
|
|
2358
2540
|
removeNodes,
|
|
2359
2541
|
getSlotEnd,
|
|
2360
2542
|
resolvePath,
|
|
2361
|
-
startTransition,
|
|
2362
|
-
useTransition,
|
|
2363
|
-
useDeferredValue,
|
|
2364
|
-
batch2 as batch,
|
|
2365
|
-
untrack2 as untrack,
|
|
2366
2543
|
isReactive,
|
|
2367
2544
|
nonReactive,
|
|
2368
2545
|
reactive,
|
|
@@ -2407,4 +2584,4 @@ export {
|
|
|
2407
2584
|
createElement,
|
|
2408
2585
|
template
|
|
2409
2586
|
};
|
|
2410
|
-
//# sourceMappingURL=chunk-
|
|
2587
|
+
//# sourceMappingURL=chunk-T2LNV5Q5.js.map
|