@fictjs/runtime 0.0.14 → 0.1.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 +8 -8
- package/dist/advanced.js +3 -3
- package/dist/{chunk-PMF6MWEV.cjs → chunk-7WAGAQLT.cjs} +45 -24
- package/dist/chunk-7WAGAQLT.cjs.map +1 -0
- package/dist/{chunk-RY4WDS6R.js → chunk-BWZFJXUI.js} +32 -11
- package/dist/chunk-BWZFJXUI.js.map +1 -0
- package/dist/{chunk-F3AIYQB7.js → chunk-CF3OHML2.js} +3 -3
- package/dist/chunk-CF3OHML2.js.map +1 -0
- package/dist/{chunk-GJTYOFMO.cjs → chunk-Q4EN6BXV.cjs} +16 -16
- package/dist/{chunk-GJTYOFMO.cjs.map → chunk-Q4EN6BXV.cjs.map} +1 -1
- package/dist/{chunk-IUZXKAAY.js → chunk-V62XZLDU.js} +2 -2
- package/dist/{chunk-624QY53A.cjs → chunk-YQ4IB7NC.cjs} +7 -7
- package/dist/chunk-YQ4IB7NC.cjs.map +1 -0
- package/dist/index.cjs +44 -44
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.dev.js +30 -9
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/internal.cjs +44 -35
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +6 -1
- package/dist/internal.d.ts +6 -1
- package/dist/internal.js +12 -3
- package/dist/internal.js.map +1 -1
- package/dist/{props-ES0Ag_Wd.d.ts → props-BBi8Tkks.d.ts} +9 -2
- package/dist/{props-CrOMYbLv.d.cts → props-BfmSLuyp.d.cts} +9 -2
- package/package.json +1 -1
- package/src/binding.ts +4 -3
- package/src/constants.ts +2 -3
- package/src/dev-entry.ts +22 -0
- package/src/lifecycle.ts +11 -3
- package/src/list-helpers.ts +14 -3
- package/src/props.ts +29 -3
- package/src/scope.ts +1 -1
- package/dist/chunk-624QY53A.cjs.map +0 -1
- package/dist/chunk-F3AIYQB7.js.map +0 -1
- package/dist/chunk-PMF6MWEV.cjs.map +0 -1
- package/dist/chunk-RY4WDS6R.js.map +0 -1
- /package/dist/{chunk-IUZXKAAY.js.map → chunk-V62XZLDU.js.map} +0 -0
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
isReactive,
|
|
5
5
|
onCleanup,
|
|
6
6
|
registerRootCleanup
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BWZFJXUI.js";
|
|
8
8
|
|
|
9
9
|
// src/scope.ts
|
|
10
10
|
function createScope() {
|
|
@@ -17,7 +17,7 @@ function createScope() {
|
|
|
17
17
|
};
|
|
18
18
|
const run = (fn) => {
|
|
19
19
|
stop();
|
|
20
|
-
const { dispose: rootDispose, value } = createRoot(fn);
|
|
20
|
+
const { dispose: rootDispose, value } = createRoot(fn, { inherit: true });
|
|
21
21
|
dispose = rootDispose;
|
|
22
22
|
return value;
|
|
23
23
|
};
|
|
@@ -42,4 +42,4 @@ export {
|
|
|
42
42
|
createScope,
|
|
43
43
|
runInScope
|
|
44
44
|
};
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
45
|
+
//# sourceMappingURL=chunk-CF3OHML2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/scope.ts"],"sourcesContent":["import { isReactive, type MaybeReactive } from './binding'\nimport { createEffect } from './effect'\nimport { createRoot, onCleanup, registerRootCleanup } from './lifecycle'\n\nexport { effectScope } from './signal'\n\nexport interface ReactiveScope {\n run<T>(fn: () => T): T\n stop(): void\n}\n\n/**\n * Create an explicit reactive scope that can contain effects/memos and be stopped manually.\n * The scope registers with the current root for cleanup.\n */\nexport function createScope(): ReactiveScope {\n let dispose: (() => void) | null = null\n\n const stop = () => {\n if (dispose) {\n dispose()\n dispose = null\n }\n }\n\n const run = <T>(fn: () => T): T => {\n stop()\n const { dispose: rootDispose, value } = createRoot(fn, { inherit: true })\n dispose = rootDispose\n return value\n }\n\n registerRootCleanup(stop)\n return { run, stop }\n}\n\n/**\n * Run a block of reactive code inside a managed scope that follows a boolean flag.\n * When the flag turns false, the scope is disposed and all contained effects/memos are cleaned up.\n */\nexport function runInScope(flag: MaybeReactive<boolean>, fn: () => void): void {\n const scope = createScope()\n const evaluate = () => (isReactive(flag) ? (flag as () => boolean)() : !!flag)\n\n createEffect(() => {\n const enabled = evaluate()\n if (enabled) {\n scope.run(fn)\n } else {\n scope.stop()\n }\n })\n\n onCleanup(scope.stop)\n}\n"],"mappings":";;;;;;;;;AAeO,SAAS,cAA6B;AAC3C,MAAI,UAA+B;AAEnC,QAAM,OAAO,MAAM;AACjB,QAAI,SAAS;AACX,cAAQ;AACR,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,MAAM,CAAI,OAAmB;AACjC,SAAK;AACL,UAAM,EAAE,SAAS,aAAa,MAAM,IAAI,WAAW,IAAI,EAAE,SAAS,KAAK,CAAC;AACxE,cAAU;AACV,WAAO;AAAA,EACT;AAEA,sBAAoB,IAAI;AACxB,SAAO,EAAE,KAAK,KAAK;AACrB;AAMO,SAAS,WAAW,MAA8B,IAAsB;AAC7E,QAAM,QAAQ,YAAY;AAC1B,QAAM,WAAW,MAAO,WAAW,IAAI,IAAK,KAAuB,IAAI,CAAC,CAAC;AAEzE,eAAa,MAAM;AACjB,UAAM,UAAU,SAAS;AACzB,QAAI,SAAS;AACX,YAAM,IAAI,EAAE;AAAA,IACd,OAAO;AACL,YAAM,KAAK;AAAA,IACb;AAAA,EACF,CAAC;AAED,YAAU,MAAM,IAAI;AACtB;","names":[]}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunk7WAGAQLTcjs = require('./chunk-7WAGAQLT.cjs');
|
|
14
14
|
|
|
15
15
|
// src/context.ts
|
|
16
16
|
var contextStorage = /* @__PURE__ */ new WeakMap();
|
|
@@ -30,8 +30,8 @@ function createContext(defaultValue) {
|
|
|
30
30
|
Provider: null
|
|
31
31
|
};
|
|
32
32
|
context.Provider = function Provider(props) {
|
|
33
|
-
const hostRoot =
|
|
34
|
-
const providerRoot =
|
|
33
|
+
const hostRoot = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
|
|
34
|
+
const providerRoot = _chunk7WAGAQLTcjs.createRootContext.call(void 0, hostRoot);
|
|
35
35
|
const contextMap = getContextMap(providerRoot);
|
|
36
36
|
contextMap.set(id, props.value);
|
|
37
37
|
const fragment = document.createDocumentFragment();
|
|
@@ -45,32 +45,32 @@ function createContext(defaultValue) {
|
|
|
45
45
|
cleanup = void 0;
|
|
46
46
|
}
|
|
47
47
|
if (activeNodes.length) {
|
|
48
|
-
|
|
48
|
+
_chunk7WAGAQLTcjs.removeNodes.call(void 0, activeNodes);
|
|
49
49
|
activeNodes = [];
|
|
50
50
|
}
|
|
51
51
|
if (children == null || children === false) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
const prev =
|
|
54
|
+
const prev = _chunk7WAGAQLTcjs.pushRoot.call(void 0, providerRoot);
|
|
55
55
|
let nodes = [];
|
|
56
56
|
try {
|
|
57
|
-
const output =
|
|
58
|
-
nodes =
|
|
57
|
+
const output = _chunk7WAGAQLTcjs.createElement.call(void 0, children);
|
|
58
|
+
nodes = _chunk7WAGAQLTcjs.toNodeArray.call(void 0, output);
|
|
59
59
|
const parentNode = marker.parentNode;
|
|
60
60
|
if (parentNode) {
|
|
61
|
-
|
|
61
|
+
_chunk7WAGAQLTcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
|
|
62
62
|
}
|
|
63
63
|
} finally {
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
_chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
|
|
65
|
+
_chunk7WAGAQLTcjs.flushOnMount.call(void 0, providerRoot);
|
|
66
66
|
}
|
|
67
67
|
cleanup = () => {
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
_chunk7WAGAQLTcjs.destroyRoot.call(void 0, providerRoot);
|
|
69
|
+
_chunk7WAGAQLTcjs.removeNodes.call(void 0, nodes);
|
|
70
70
|
};
|
|
71
71
|
activeNodes = nodes;
|
|
72
72
|
};
|
|
73
|
-
|
|
73
|
+
_chunk7WAGAQLTcjs.createRenderEffect.call(void 0, () => {
|
|
74
74
|
contextMap.set(id, props.value);
|
|
75
75
|
renderChildren(props.children);
|
|
76
76
|
});
|
|
@@ -79,7 +79,7 @@ function createContext(defaultValue) {
|
|
|
79
79
|
return context;
|
|
80
80
|
}
|
|
81
81
|
function useContext(context) {
|
|
82
|
-
let root =
|
|
82
|
+
let root = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
|
|
83
83
|
while (root) {
|
|
84
84
|
const contextMap = contextStorage.get(root);
|
|
85
85
|
if (contextMap && contextMap.has(context.id)) {
|
|
@@ -90,7 +90,7 @@ function useContext(context) {
|
|
|
90
90
|
return context.defaultValue;
|
|
91
91
|
}
|
|
92
92
|
function hasContext(context) {
|
|
93
|
-
let root =
|
|
93
|
+
let root = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
|
|
94
94
|
while (root) {
|
|
95
95
|
const contextMap = contextStorage.get(root);
|
|
96
96
|
if (contextMap && contextMap.has(context.id)) {
|
|
@@ -106,4 +106,4 @@ function hasContext(context) {
|
|
|
106
106
|
|
|
107
107
|
|
|
108
108
|
exports.createContext = createContext; exports.useContext = useContext; exports.hasContext = hasContext;
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
109
|
+
//# sourceMappingURL=chunk-Q4EN6BXV.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/chunk-GJTYOFMO.cjs","../src/context.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fict/fict/packages/runtime/dist/chunk-GJTYOFMO.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 {\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 { createRenderEffect } from './effect'\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-Q4EN6BXV.cjs","../src/context.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fict/fict/packages/runtime/dist/chunk-Q4EN6BXV.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 {\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 { createRenderEffect } from './effect'\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"]}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
pushRoot,
|
|
11
11
|
removeNodes,
|
|
12
12
|
toNodeArray
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BWZFJXUI.js";
|
|
14
14
|
|
|
15
15
|
// src/context.ts
|
|
16
16
|
var contextStorage = /* @__PURE__ */ new WeakMap();
|
|
@@ -106,4 +106,4 @@ export {
|
|
|
106
106
|
useContext,
|
|
107
107
|
hasContext
|
|
108
108
|
};
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
109
|
+
//# sourceMappingURL=chunk-V62XZLDU.js.map
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunk7WAGAQLTcjs = require('./chunk-7WAGAQLT.cjs');
|
|
8
8
|
|
|
9
9
|
// src/scope.ts
|
|
10
10
|
function createScope() {
|
|
@@ -17,17 +17,17 @@ function createScope() {
|
|
|
17
17
|
};
|
|
18
18
|
const run = (fn) => {
|
|
19
19
|
stop();
|
|
20
|
-
const { dispose: rootDispose, value } =
|
|
20
|
+
const { dispose: rootDispose, value } = _chunk7WAGAQLTcjs.createRoot.call(void 0, fn, { inherit: true });
|
|
21
21
|
dispose = rootDispose;
|
|
22
22
|
return value;
|
|
23
23
|
};
|
|
24
|
-
|
|
24
|
+
_chunk7WAGAQLTcjs.registerRootCleanup.call(void 0, stop);
|
|
25
25
|
return { run, stop };
|
|
26
26
|
}
|
|
27
27
|
function runInScope(flag, fn) {
|
|
28
28
|
const scope = createScope();
|
|
29
|
-
const evaluate = () =>
|
|
30
|
-
|
|
29
|
+
const evaluate = () => _chunk7WAGAQLTcjs.isReactive.call(void 0, flag) ? flag() : !!flag;
|
|
30
|
+
_chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
|
|
31
31
|
const enabled = evaluate();
|
|
32
32
|
if (enabled) {
|
|
33
33
|
scope.run(fn);
|
|
@@ -35,11 +35,11 @@ function runInScope(flag, fn) {
|
|
|
35
35
|
scope.stop();
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
|
-
|
|
38
|
+
_chunk7WAGAQLTcjs.onCleanup.call(void 0, scope.stop);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
exports.createScope = createScope; exports.runInScope = runInScope;
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
45
|
+
//# sourceMappingURL=chunk-YQ4IB7NC.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/chunk-YQ4IB7NC.cjs","../src/scope.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACOO,SAAS,WAAA,CAAA,EAA6B;AAC3C,EAAA,IAAI,QAAA,EAA+B,IAAA;AAEnC,EAAA,MAAM,KAAA,EAAO,CAAA,EAAA,GAAM;AACjB,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,CAAA;AACR,MAAA,QAAA,EAAU,IAAA;AAAA,IACZ;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,IAAA,EAAM,CAAI,EAAA,EAAA,GAAmB;AACjC,IAAA,IAAA,CAAK,CAAA;AACL,IAAA,MAAM,EAAE,OAAA,EAAS,WAAA,EAAa,MAAM,EAAA,EAAI,0CAAA,EAAW,EAAI,EAAE,OAAA,EAAS,KAAK,CAAC,CAAA;AACxE,IAAA,QAAA,EAAU,WAAA;AACV,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAEA,EAAA,mDAAA,IAAwB,CAAA;AACxB,EAAA,OAAO,EAAE,GAAA,EAAK,KAAK,CAAA;AACrB;AAMO,SAAS,UAAA,CAAW,IAAA,EAA8B,EAAA,EAAsB;AAC7E,EAAA,MAAM,MAAA,EAAQ,WAAA,CAAY,CAAA;AAC1B,EAAA,MAAM,SAAA,EAAW,CAAA,EAAA,GAAO,0CAAA,IAAe,EAAA,EAAK,IAAA,CAAuB,EAAA,EAAI,CAAC,CAAC,IAAA;AAEzE,EAAA,4CAAA,CAAa,EAAA,GAAM;AACjB,IAAA,MAAM,QAAA,EAAU,QAAA,CAAS,CAAA;AACzB,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AAAA,IACd,EAAA,KAAO;AACL,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA;AAAA,IACb;AAAA,EACF,CAAC,CAAA;AAED,EAAA,yCAAA,KAAU,CAAM,IAAI,CAAA;AACtB;ADfA;AACA;AACE;AACA;AACF,mEAAC","file":"/home/runner/work/fict/fict/packages/runtime/dist/chunk-YQ4IB7NC.cjs","sourcesContent":[null,"import { isReactive, type MaybeReactive } from './binding'\nimport { createEffect } from './effect'\nimport { createRoot, onCleanup, registerRootCleanup } from './lifecycle'\n\nexport { effectScope } from './signal'\n\nexport interface ReactiveScope {\n run<T>(fn: () => T): T\n stop(): void\n}\n\n/**\n * Create an explicit reactive scope that can contain effects/memos and be stopped manually.\n * The scope registers with the current root for cleanup.\n */\nexport function createScope(): ReactiveScope {\n let dispose: (() => void) | null = null\n\n const stop = () => {\n if (dispose) {\n dispose()\n dispose = null\n }\n }\n\n const run = <T>(fn: () => T): T => {\n stop()\n const { dispose: rootDispose, value } = createRoot(fn, { inherit: true })\n dispose = rootDispose\n return value\n }\n\n registerRootCleanup(stop)\n return { run, stop }\n}\n\n/**\n * Run a block of reactive code inside a managed scope that follows a boolean flag.\n * When the flag turns false, the scope is disposed and all contained effects/memos are cleaned up.\n */\nexport function runInScope(flag: MaybeReactive<boolean>, fn: () => void): void {\n const scope = createScope()\n const evaluate = () => (isReactive(flag) ? (flag as () => boolean)() : !!flag)\n\n createEffect(() => {\n const enabled = evaluate()\n if (enabled) {\n scope.run(fn)\n } else {\n scope.stop()\n }\n })\n\n onCleanup(scope.stop)\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkQ4EN6BXVcjs = require('./chunk-Q4EN6BXV.cjs');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -34,7 +34,7 @@ var _chunkGJTYOFMOcjs = require('./chunk-GJTYOFMO.cjs');
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
var
|
|
37
|
+
var _chunk7WAGAQLTcjs = require('./chunk-7WAGAQLT.cjs');
|
|
38
38
|
|
|
39
39
|
// src/ref.ts
|
|
40
40
|
function createRef() {
|
|
@@ -46,8 +46,8 @@ function ErrorBoundary(props) {
|
|
|
46
46
|
const fragment = document.createDocumentFragment();
|
|
47
47
|
const marker = document.createComment("fict:error-boundary");
|
|
48
48
|
fragment.appendChild(marker);
|
|
49
|
-
const currentView =
|
|
50
|
-
const hostRoot =
|
|
49
|
+
const currentView = _chunk7WAGAQLTcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
|
|
50
|
+
const hostRoot = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
|
|
51
51
|
let cleanup;
|
|
52
52
|
let activeNodes = [];
|
|
53
53
|
let renderingFallback = false;
|
|
@@ -63,26 +63,26 @@ function ErrorBoundary(props) {
|
|
|
63
63
|
cleanup = void 0;
|
|
64
64
|
}
|
|
65
65
|
if (activeNodes.length) {
|
|
66
|
-
|
|
66
|
+
_chunk7WAGAQLTcjs.removeNodes.call(void 0, activeNodes);
|
|
67
67
|
activeNodes = [];
|
|
68
68
|
}
|
|
69
69
|
if (value == null || value === false) {
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
|
-
const root =
|
|
73
|
-
const prev =
|
|
72
|
+
const root = _chunk7WAGAQLTcjs.createRootContext.call(void 0, hostRoot);
|
|
73
|
+
const prev = _chunk7WAGAQLTcjs.pushRoot.call(void 0, root);
|
|
74
74
|
let nodes = [];
|
|
75
75
|
try {
|
|
76
|
-
const output =
|
|
77
|
-
nodes =
|
|
76
|
+
const output = _chunk7WAGAQLTcjs.createElement.call(void 0, value);
|
|
77
|
+
nodes = _chunk7WAGAQLTcjs.toNodeArray.call(void 0, output);
|
|
78
78
|
const parentNode = marker.parentNode;
|
|
79
79
|
if (parentNode) {
|
|
80
|
-
|
|
80
|
+
_chunk7WAGAQLTcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
|
|
81
81
|
}
|
|
82
82
|
} catch (err) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
_chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
|
|
84
|
+
_chunk7WAGAQLTcjs.flushOnMount.call(void 0, root);
|
|
85
|
+
_chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
|
|
86
86
|
if (renderingFallback) {
|
|
87
87
|
throw err;
|
|
88
88
|
}
|
|
@@ -97,19 +97,19 @@ function ErrorBoundary(props) {
|
|
|
97
97
|
}
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
_chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
|
|
101
|
+
_chunk7WAGAQLTcjs.flushOnMount.call(void 0, root);
|
|
102
102
|
cleanup = () => {
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
_chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
|
|
104
|
+
_chunk7WAGAQLTcjs.removeNodes.call(void 0, nodes);
|
|
105
105
|
};
|
|
106
106
|
activeNodes = nodes;
|
|
107
107
|
};
|
|
108
|
-
|
|
108
|
+
_chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
|
|
109
109
|
const value = currentView();
|
|
110
110
|
renderValue(value);
|
|
111
111
|
});
|
|
112
|
-
|
|
112
|
+
_chunk7WAGAQLTcjs.registerErrorHandler.call(void 0, (err) => {
|
|
113
113
|
renderValue(toView(err));
|
|
114
114
|
_optionalChain([props, 'access', _5 => _5.onError, 'optionalCall', _6 => _6(err)]);
|
|
115
115
|
return true;
|
|
@@ -118,7 +118,7 @@ function ErrorBoundary(props) {
|
|
|
118
118
|
const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
|
|
119
119
|
const getter = isGetter ? props.resetKeys : void 0;
|
|
120
120
|
let prev = isGetter ? getter() : props.resetKeys;
|
|
121
|
-
|
|
121
|
+
_chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
|
|
122
122
|
const next = getter ? getter() : props.resetKeys;
|
|
123
123
|
if (prev !== next) {
|
|
124
124
|
prev = next;
|
|
@@ -147,11 +147,11 @@ function createSuspenseToken() {
|
|
|
147
147
|
}
|
|
148
148
|
var isThenable = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
|
|
149
149
|
function Suspense(props) {
|
|
150
|
-
const currentView =
|
|
151
|
-
const pending =
|
|
150
|
+
const currentView = _chunk7WAGAQLTcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
|
|
151
|
+
const pending = _chunk7WAGAQLTcjs.signal.call(void 0, 0);
|
|
152
152
|
let resolvedOnce = false;
|
|
153
153
|
let epoch = 0;
|
|
154
|
-
const hostRoot =
|
|
154
|
+
const hostRoot = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
|
|
155
155
|
const toFallback = (err) => typeof props.fallback === "function" ? props.fallback(err) : props.fallback;
|
|
156
156
|
const switchView = (view) => {
|
|
157
157
|
currentView(view);
|
|
@@ -163,42 +163,42 @@ function Suspense(props) {
|
|
|
163
163
|
cleanup = void 0;
|
|
164
164
|
}
|
|
165
165
|
if (activeNodes.length) {
|
|
166
|
-
|
|
166
|
+
_chunk7WAGAQLTcjs.removeNodes.call(void 0, activeNodes);
|
|
167
167
|
activeNodes = [];
|
|
168
168
|
}
|
|
169
169
|
if (view == null || view === false) {
|
|
170
170
|
return;
|
|
171
171
|
}
|
|
172
|
-
const root =
|
|
173
|
-
const prev =
|
|
172
|
+
const root = _chunk7WAGAQLTcjs.createRootContext.call(void 0, hostRoot);
|
|
173
|
+
const prev = _chunk7WAGAQLTcjs.pushRoot.call(void 0, root);
|
|
174
174
|
let nodes = [];
|
|
175
175
|
try {
|
|
176
|
-
const output =
|
|
177
|
-
nodes =
|
|
176
|
+
const output = _chunk7WAGAQLTcjs.createElement.call(void 0, view);
|
|
177
|
+
nodes = _chunk7WAGAQLTcjs.toNodeArray.call(void 0, output);
|
|
178
178
|
const suspendedAttempt = nodes.length > 0 && nodes.every((node) => node instanceof Comment && node.data === "fict:suspend");
|
|
179
179
|
if (suspendedAttempt) {
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
_chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
|
|
181
|
+
_chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
|
|
182
182
|
return;
|
|
183
183
|
}
|
|
184
184
|
const parentNode = marker.parentNode;
|
|
185
185
|
if (parentNode) {
|
|
186
|
-
|
|
186
|
+
_chunk7WAGAQLTcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
|
|
187
187
|
}
|
|
188
188
|
} catch (err) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if (!
|
|
189
|
+
_chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
|
|
190
|
+
_chunk7WAGAQLTcjs.flushOnMount.call(void 0, root);
|
|
191
|
+
_chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
|
|
192
|
+
if (!_chunk7WAGAQLTcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
|
|
193
193
|
throw err;
|
|
194
194
|
}
|
|
195
195
|
return;
|
|
196
196
|
}
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
_chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
|
|
198
|
+
_chunk7WAGAQLTcjs.flushOnMount.call(void 0, root);
|
|
199
199
|
cleanup = () => {
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
_chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
|
|
201
|
+
_chunk7WAGAQLTcjs.removeNodes.call(void 0, nodes);
|
|
202
202
|
};
|
|
203
203
|
activeNodes = nodes;
|
|
204
204
|
};
|
|
@@ -213,7 +213,7 @@ function Suspense(props) {
|
|
|
213
213
|
_optionalChain([props, 'access', _7 => _7.onResolve, 'optionalCall', _8 => _8()]);
|
|
214
214
|
}
|
|
215
215
|
};
|
|
216
|
-
|
|
216
|
+
_chunk7WAGAQLTcjs.registerSuspenseHandler.call(void 0, (token) => {
|
|
217
217
|
const tokenEpoch = epoch;
|
|
218
218
|
pending(pending() + 1);
|
|
219
219
|
switchView(toFallback());
|
|
@@ -238,7 +238,7 @@ function Suspense(props) {
|
|
|
238
238
|
const newPending = Math.max(0, pending() - 1);
|
|
239
239
|
pending(newPending);
|
|
240
240
|
_optionalChain([props, 'access', _9 => _9.onReject, 'optionalCall', _10 => _10(err)]);
|
|
241
|
-
if (!
|
|
241
|
+
if (!_chunk7WAGAQLTcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
|
|
242
242
|
throw err;
|
|
243
243
|
}
|
|
244
244
|
}
|
|
@@ -247,14 +247,14 @@ function Suspense(props) {
|
|
|
247
247
|
}
|
|
248
248
|
return false;
|
|
249
249
|
});
|
|
250
|
-
|
|
250
|
+
_chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
|
|
251
251
|
renderView(currentView());
|
|
252
252
|
});
|
|
253
253
|
if (props.resetKeys !== void 0) {
|
|
254
254
|
const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
|
|
255
255
|
const getter = isGetter ? props.resetKeys : void 0;
|
|
256
256
|
let prev = isGetter ? getter() : props.resetKeys;
|
|
257
|
-
|
|
257
|
+
_chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
|
|
258
258
|
const next = getter ? getter() : props.resetKeys;
|
|
259
259
|
if (prev !== next) {
|
|
260
260
|
prev = next;
|
|
@@ -291,5 +291,5 @@ function Suspense(props) {
|
|
|
291
291
|
|
|
292
292
|
|
|
293
293
|
|
|
294
|
-
exports.ErrorBoundary = ErrorBoundary; exports.Fragment =
|
|
294
|
+
exports.ErrorBoundary = ErrorBoundary; exports.Fragment = _chunk7WAGAQLTcjs.Fragment; exports.Suspense = Suspense; exports.batch = _chunk7WAGAQLTcjs.batch2; exports.createContext = _chunkQ4EN6BXVcjs.createContext; exports.createEffect = _chunk7WAGAQLTcjs.createEffect; exports.createElement = _chunk7WAGAQLTcjs.createElement; exports.createMemo = _chunk7WAGAQLTcjs.createMemo; exports.createPortal = _chunk7WAGAQLTcjs.createPortal; exports.createRef = createRef; exports.createRoot = _chunk7WAGAQLTcjs.createRoot; exports.createSuspenseToken = createSuspenseToken; exports.hasContext = _chunkQ4EN6BXVcjs.hasContext; exports.mergeProps = _chunk7WAGAQLTcjs.mergeProps; exports.onCleanup = _chunk7WAGAQLTcjs.onCleanup; exports.onDestroy = _chunk7WAGAQLTcjs.onDestroy; exports.onMount = _chunk7WAGAQLTcjs.onMount; exports.prop = _chunk7WAGAQLTcjs.prop; exports.render = _chunk7WAGAQLTcjs.render; exports.startTransition = _chunk7WAGAQLTcjs.startTransition; exports.untrack = _chunk7WAGAQLTcjs.untrack2; exports.useContext = _chunkQ4EN6BXVcjs.useContext; exports.useDeferredValue = _chunk7WAGAQLTcjs.useDeferredValue; exports.useTransition = _chunk7WAGAQLTcjs.useTransition;
|
|
295
295
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-
|
|
1
|
+
export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-BfmSLuyp.cjs';
|
|
2
2
|
import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-Auji1rz9.cjs';
|
|
3
3
|
export { p as ClassProp, C as Cleanup, l as Component, D as DOMElement, E as Effect, r as ErrorInfo, q as EventHandler, k as FictVNode, P as PropsWithChildren, m as Ref, n as RefCallback, o as StyleProp, h as createEffect, j as createPortal } from './effect-Auji1rz9.cjs';
|
|
4
4
|
export { C as Context, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-UXySaqI_.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-
|
|
1
|
+
export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-BBi8Tkks.js';
|
|
2
2
|
import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-Auji1rz9.js';
|
|
3
3
|
export { p as ClassProp, C as Cleanup, l as Component, D as DOMElement, E as Effect, r as ErrorInfo, q as EventHandler, k as FictVNode, P as PropsWithChildren, m as Ref, n as RefCallback, o as StyleProp, h as createEffect, j as createPortal } from './effect-Auji1rz9.js';
|
|
4
4
|
export { C as Context, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-B7UYnfzM.js';
|
package/dist/index.dev.js
CHANGED
|
@@ -132,7 +132,7 @@ var currentRoot;
|
|
|
132
132
|
var currentEffectCleanups;
|
|
133
133
|
var globalErrorHandlers = /* @__PURE__ */ new WeakMap();
|
|
134
134
|
var globalSuspenseHandlers = /* @__PURE__ */ new WeakMap();
|
|
135
|
-
function createRootContext(parent
|
|
135
|
+
function createRootContext(parent) {
|
|
136
136
|
return { parent, cleanups: [], destroyCallbacks: [] };
|
|
137
137
|
}
|
|
138
138
|
function pushRoot(root) {
|
|
@@ -208,8 +208,9 @@ function destroyRoot(root) {
|
|
|
208
208
|
globalSuspenseHandlers.delete(root);
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
-
function createRoot(fn) {
|
|
212
|
-
const
|
|
211
|
+
function createRoot(fn, options) {
|
|
212
|
+
const parent = options?.inherit ? currentRoot : void 0;
|
|
213
|
+
const root = createRootContext(parent);
|
|
213
214
|
const prev = pushRoot(root);
|
|
214
215
|
let value;
|
|
215
216
|
try {
|
|
@@ -1301,8 +1302,7 @@ function getPropAlias(prop2, tagName) {
|
|
|
1301
1302
|
return a;
|
|
1302
1303
|
}
|
|
1303
1304
|
var $$EVENTS = "_$FICT_DELEGATE";
|
|
1304
|
-
var
|
|
1305
|
-
var DelegatedEvents = new Set(delegatedEvents);
|
|
1305
|
+
var DelegatedEvents = new Set(DelegatedEventNames);
|
|
1306
1306
|
var svgElements = isDev4 ? [
|
|
1307
1307
|
"altGlyph",
|
|
1308
1308
|
"altGlyphDef",
|
|
@@ -1907,7 +1907,8 @@ function bindEvent(el, eventName, handler, options) {
|
|
|
1907
1907
|
if (handler == null) return () => {
|
|
1908
1908
|
};
|
|
1909
1909
|
const rootRef = getCurrentRoot();
|
|
1910
|
-
|
|
1910
|
+
const shouldDelegate = options == null && DelegatedEvents.has(eventName);
|
|
1911
|
+
if (shouldDelegate) {
|
|
1911
1912
|
const key = `$$${eventName}`;
|
|
1912
1913
|
delegateEvents([eventName]);
|
|
1913
1914
|
const resolveHandler = isReactive(handler) ? handler : () => handler;
|
|
@@ -2026,17 +2027,27 @@ function __fictPopContext() {
|
|
|
2026
2027
|
}
|
|
2027
2028
|
|
|
2028
2029
|
// src/props.ts
|
|
2030
|
+
var PROP_GETTER_MARKER = Symbol.for("fict:prop-getter");
|
|
2029
2031
|
var propGetters = /* @__PURE__ */ new WeakSet();
|
|
2030
2032
|
var rawToProxy = /* @__PURE__ */ new WeakMap();
|
|
2031
2033
|
var proxyToRaw = /* @__PURE__ */ new WeakMap();
|
|
2032
2034
|
function __fictProp(getter) {
|
|
2033
2035
|
if (typeof getter === "function" && getter.length === 0) {
|
|
2034
2036
|
propGetters.add(getter);
|
|
2037
|
+
if (Object.isExtensible(getter)) {
|
|
2038
|
+
try {
|
|
2039
|
+
;
|
|
2040
|
+
getter[PROP_GETTER_MARKER] = true;
|
|
2041
|
+
} catch {
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2035
2044
|
}
|
|
2036
2045
|
return getter;
|
|
2037
2046
|
}
|
|
2038
2047
|
function isPropGetter(value) {
|
|
2039
|
-
|
|
2048
|
+
if (typeof value !== "function") return false;
|
|
2049
|
+
const fn = value;
|
|
2050
|
+
return propGetters.has(fn) || fn[PROP_GETTER_MARKER] === true;
|
|
2040
2051
|
}
|
|
2041
2052
|
function createPropsProxy(props) {
|
|
2042
2053
|
if (!props || typeof props !== "object") {
|
|
@@ -2150,11 +2161,21 @@ function mergeProps(...sources) {
|
|
|
2150
2161
|
}
|
|
2151
2162
|
});
|
|
2152
2163
|
}
|
|
2153
|
-
function prop(getter) {
|
|
2164
|
+
function prop(getter, options) {
|
|
2154
2165
|
if (isPropGetter(getter)) {
|
|
2155
2166
|
return getter;
|
|
2156
2167
|
}
|
|
2157
|
-
|
|
2168
|
+
const fn = getter;
|
|
2169
|
+
const unwrap = options?.unwrap !== false;
|
|
2170
|
+
return __fictProp(
|
|
2171
|
+
createMemo(() => {
|
|
2172
|
+
const value = fn();
|
|
2173
|
+
if (unwrap && isPropGetter(value)) {
|
|
2174
|
+
return value();
|
|
2175
|
+
}
|
|
2176
|
+
return value;
|
|
2177
|
+
})
|
|
2178
|
+
);
|
|
2158
2179
|
}
|
|
2159
2180
|
|
|
2160
2181
|
// src/dom.ts
|