fict 0.19.0 → 0.21.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 +8 -0
- package/dist/advanced.cjs +20 -0
- package/dist/advanced.d.cts +1 -1
- package/dist/advanced.d.ts +1 -1
- package/dist/advanced.js +1 -1
- package/dist/{chunk-43IPAXWW.js → chunk-7CM2UZ6M.js} +13 -24
- package/dist/chunk-7CM2UZ6M.js.map +1 -0
- package/dist/chunk-TKWIPOL2.js +9 -0
- package/dist/chunk-TKWIPOL2.js.map +1 -0
- package/dist/index.cjs +18 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/plus.cjs +13 -24
- package/dist/plus.cjs.map +1 -1
- package/dist/plus.d.cts +7 -6
- package/dist/plus.d.ts +7 -6
- package/dist/plus.js +4 -4
- package/dist/plus.js.map +1 -1
- package/dist/slim.cjs +8 -2
- package/dist/slim.cjs.map +1 -1
- package/dist/slim.js +4 -2
- package/dist/slim.js.map +1 -1
- package/package.json +4 -4
- package/src/advanced.ts +6 -0
- package/src/index.ts +6 -3
- package/src/internal.ts +8 -4
- package/src/macro-diagnostics.ts +7 -0
- package/src/resource.ts +10 -9
- package/src/slim.ts +4 -2
- package/src/store.ts +13 -19
- package/dist/chunk-43IPAXWW.js.map +0 -1
package/README.md
CHANGED
|
@@ -30,3 +30,11 @@ yarn add fict
|
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
You can visit [Fict](https://github.com/fictjs/fict) for more documentation.
|
|
33
|
+
|
|
34
|
+
## Package Surfaces
|
|
35
|
+
|
|
36
|
+
- `fict`: application-facing API and compiler macros (`$state`, `$effect`).
|
|
37
|
+
- `fict/plus`: async resource and lazy component helpers.
|
|
38
|
+
- `fict/advanced`: escape hatches for library authors and low-level reactive integration.
|
|
39
|
+
- `fict/loader`: SSR/resume loader entrypoint.
|
|
40
|
+
- `fict/internal`: compiler ABI for generated code only; do not import by hand.
|
package/dist/advanced.cjs
CHANGED
|
@@ -4,6 +4,14 @@ var advanced = require('@fictjs/runtime/advanced');
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
Object.defineProperty(exports, "FICT_DEVTOOLS_MIN_PROTOCOL_VERSION", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return advanced.FICT_DEVTOOLS_MIN_PROTOCOL_VERSION; }
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(exports, "FICT_DEVTOOLS_PROTOCOL_VERSION", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () { return advanced.FICT_DEVTOOLS_PROTOCOL_VERSION; }
|
|
14
|
+
});
|
|
7
15
|
Object.defineProperty(exports, "createAttributeBinding", {
|
|
8
16
|
enumerable: true,
|
|
9
17
|
get: function () { return advanced.createAttributeBinding; }
|
|
@@ -64,10 +72,22 @@ Object.defineProperty(exports, "hasContext", {
|
|
|
64
72
|
enumerable: true,
|
|
65
73
|
get: function () { return advanced.hasContext; }
|
|
66
74
|
});
|
|
75
|
+
Object.defineProperty(exports, "isDevtoolsHookCompatible", {
|
|
76
|
+
enumerable: true,
|
|
77
|
+
get: function () { return advanced.isDevtoolsHookCompatible; }
|
|
78
|
+
});
|
|
67
79
|
Object.defineProperty(exports, "isReactive", {
|
|
68
80
|
enumerable: true,
|
|
69
81
|
get: function () { return advanced.isReactive; }
|
|
70
82
|
});
|
|
83
|
+
Object.defineProperty(exports, "nonReactive", {
|
|
84
|
+
enumerable: true,
|
|
85
|
+
get: function () { return advanced.nonReactive; }
|
|
86
|
+
});
|
|
87
|
+
Object.defineProperty(exports, "reactive", {
|
|
88
|
+
enumerable: true,
|
|
89
|
+
get: function () { return advanced.reactive; }
|
|
90
|
+
});
|
|
71
91
|
Object.defineProperty(exports, "runInScope", {
|
|
72
92
|
enumerable: true,
|
|
73
93
|
get: function () { return advanced.runInScope; }
|
package/dist/advanced.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Context, FictDevtoolsHook, ProviderProps, ReactiveScope, Signal, VersionedSignal, VersionedSignalOptions, createAttributeBinding, createChildBinding, createClassBinding, createContext, createRenderEffect, createScope, createSelector, createShow, createSignal, createStyleBinding, createTextBinding, createVersionedSignal, effectScope, getDevtoolsHook, hasContext, isReactive, runInScope, setCycleProtectionOptions, unwrap, useContext } from '@fictjs/runtime/advanced';
|
|
1
|
+
export { Context, FICT_DEVTOOLS_MIN_PROTOCOL_VERSION, FICT_DEVTOOLS_PROTOCOL_VERSION, FictDevtoolsCompatibility, FictDevtoolsHook, ProviderProps, ReactiveScope, Signal, VersionedSignal, VersionedSignalOptions, createAttributeBinding, createChildBinding, createClassBinding, createContext, createRenderEffect, createScope, createSelector, createShow, createSignal, createStyleBinding, createTextBinding, createVersionedSignal, effectScope, getDevtoolsHook, hasContext, isDevtoolsHookCompatible, isReactive, nonReactive, reactive, runInScope, setCycleProtectionOptions, unwrap, useContext } from '@fictjs/runtime/advanced';
|
|
2
2
|
import '@fictjs/runtime/internal/list';
|
|
3
3
|
import '@fictjs/runtime/internal';
|
|
4
4
|
import '@fictjs/runtime/jsx-dev-runtime';
|
package/dist/advanced.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Context, FictDevtoolsHook, ProviderProps, ReactiveScope, Signal, VersionedSignal, VersionedSignalOptions, createAttributeBinding, createChildBinding, createClassBinding, createContext, createRenderEffect, createScope, createSelector, createShow, createSignal, createStyleBinding, createTextBinding, createVersionedSignal, effectScope, getDevtoolsHook, hasContext, isReactive, runInScope, setCycleProtectionOptions, unwrap, useContext } from '@fictjs/runtime/advanced';
|
|
1
|
+
export { Context, FICT_DEVTOOLS_MIN_PROTOCOL_VERSION, FICT_DEVTOOLS_PROTOCOL_VERSION, FictDevtoolsCompatibility, FictDevtoolsHook, ProviderProps, ReactiveScope, Signal, VersionedSignal, VersionedSignalOptions, createAttributeBinding, createChildBinding, createClassBinding, createContext, createRenderEffect, createScope, createSelector, createShow, createSignal, createStyleBinding, createTextBinding, createVersionedSignal, effectScope, getDevtoolsHook, hasContext, isDevtoolsHookCompatible, isReactive, nonReactive, reactive, runInScope, setCycleProtectionOptions, unwrap, useContext } from '@fictjs/runtime/advanced';
|
|
2
2
|
import '@fictjs/runtime/internal/list';
|
|
3
3
|
import '@fictjs/runtime/internal';
|
|
4
4
|
import '@fictjs/runtime/jsx-dev-runtime';
|
package/dist/advanced.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { createAttributeBinding, createChildBinding, createClassBinding, createContext, createRenderEffect, createScope, createSelector, createShow, createSignal, createStyleBinding, createTextBinding, createVersionedSignal, effectScope, getDevtoolsHook, hasContext, isReactive, runInScope, setCycleProtectionOptions, unwrap, useContext } from '@fictjs/runtime/advanced';
|
|
1
|
+
export { FICT_DEVTOOLS_MIN_PROTOCOL_VERSION, FICT_DEVTOOLS_PROTOCOL_VERSION, createAttributeBinding, createChildBinding, createClassBinding, createContext, createRenderEffect, createScope, createSelector, createShow, createSignal, createStyleBinding, createTextBinding, createVersionedSignal, effectScope, getDevtoolsHook, hasContext, isDevtoolsHookCompatible, isReactive, nonReactive, reactive, runInScope, setCycleProtectionOptions, unwrap, useContext } from '@fictjs/runtime/advanced';
|
|
2
2
|
//# sourceMappingURL=advanced.js.map
|
|
3
3
|
//# sourceMappingURL=advanced.js.map
|
|
@@ -5,8 +5,8 @@ var IS_STORE_PROXY = Symbol("fict-store-proxy");
|
|
|
5
5
|
var RAW_TO_PROXY = /* @__PURE__ */ new WeakMap();
|
|
6
6
|
var PROXY_CACHE = /* @__PURE__ */ new WeakMap();
|
|
7
7
|
var isDev = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
8
|
-
var MUTATION_WARNED = /* @__PURE__ */ new
|
|
9
|
-
var SKIP_MUTATION_WARNING_PROPS =
|
|
8
|
+
var MUTATION_WARNED = /* @__PURE__ */ new WeakSet();
|
|
9
|
+
var SKIP_MUTATION_WARNING_PROPS = [
|
|
10
10
|
"constructor",
|
|
11
11
|
"prototype",
|
|
12
12
|
"__proto__",
|
|
@@ -19,7 +19,7 @@ var SKIP_MUTATION_WARNING_PROPS = /* @__PURE__ */ new Set([
|
|
|
19
19
|
Symbol.toStringTag,
|
|
20
20
|
Symbol.iterator,
|
|
21
21
|
Symbol.toPrimitive
|
|
22
|
-
]
|
|
22
|
+
];
|
|
23
23
|
var SIGNAL_CACHE = /* @__PURE__ */ new WeakMap();
|
|
24
24
|
var BOUND_METHOD_CACHE = /* @__PURE__ */ new WeakMap();
|
|
25
25
|
var ITERATE_KEY = Symbol("iterate");
|
|
@@ -63,18 +63,9 @@ function $store(initialValue) {
|
|
|
63
63
|
const signal = getSignal(target, prop);
|
|
64
64
|
const trackedValue = signal();
|
|
65
65
|
const currentValue = Reflect.get(target, prop, receiver ?? proxy);
|
|
66
|
-
if (isDev && currentValue !== trackedValue && !SKIP_MUTATION_WARNING_PROPS.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
warnedProps = /* @__PURE__ */ new Set();
|
|
70
|
-
MUTATION_WARNED.set(target, warnedProps);
|
|
71
|
-
}
|
|
72
|
-
if (!warnedProps.has(prop)) {
|
|
73
|
-
warnedProps.add(prop);
|
|
74
|
-
console.warn(
|
|
75
|
-
`[fict] Direct mutation detected for "${String(prop)}"; mutate via $store proxy.`
|
|
76
|
-
);
|
|
77
|
-
}
|
|
66
|
+
if (isDev && currentValue !== trackedValue && !SKIP_MUTATION_WARNING_PROPS.includes(prop) && !MUTATION_WARNED.has(target)) {
|
|
67
|
+
MUTATION_WARNED.add(target);
|
|
68
|
+
console.warn(`[fict] Use $store for ${String(prop)}.`);
|
|
78
69
|
}
|
|
79
70
|
if (typeof currentValue === "function") {
|
|
80
71
|
let boundMethods = BOUND_METHOD_CACHE.get(target);
|
|
@@ -127,20 +118,18 @@ function $store(initialValue) {
|
|
|
127
118
|
triggerIteration(target);
|
|
128
119
|
}
|
|
129
120
|
if (Array.isArray(target) && prop !== "length") {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
signals2.length(target.length);
|
|
121
|
+
if (signals && signals.length) {
|
|
122
|
+
signals.length(target.length);
|
|
133
123
|
}
|
|
134
124
|
}
|
|
135
125
|
if (Array.isArray(target) && prop === "length") {
|
|
136
126
|
const nextLength = target.length;
|
|
137
127
|
if (typeof oldLength === "number" && nextLength < oldLength) {
|
|
138
|
-
|
|
139
|
-
if (signals2) {
|
|
128
|
+
if (signals) {
|
|
140
129
|
for (let i = nextLength; i < oldLength; i += 1) {
|
|
141
130
|
const key = String(i);
|
|
142
|
-
if (
|
|
143
|
-
|
|
131
|
+
if (signals[key]) {
|
|
132
|
+
signals[key](void 0);
|
|
144
133
|
}
|
|
145
134
|
}
|
|
146
135
|
}
|
|
@@ -183,5 +172,5 @@ function $store(initialValue) {
|
|
|
183
172
|
}
|
|
184
173
|
|
|
185
174
|
export { $store };
|
|
186
|
-
//# sourceMappingURL=chunk-
|
|
187
|
-
//# sourceMappingURL=chunk-
|
|
175
|
+
//# sourceMappingURL=chunk-7CM2UZ6M.js.map
|
|
176
|
+
//# sourceMappingURL=chunk-7CM2UZ6M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/store.ts"],"names":[],"mappings":"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","file":"chunk-7CM2UZ6M.js","sourcesContent":["/**\n * @fileoverview Deep reactive store implementation for Fict.\n *\n * $store creates a deeply reactive proxy that tracks property access at the path level.\n * Unlike $state (which is shallow), $store allows direct mutation of nested properties.\n *\n * @example\n * ```typescript\n * const user = $store({ name: 'Alice', address: { city: 'London' } })\n * user.address.city = 'Paris' // Fine-grained reactive update\n * ```\n */\n\nimport { createSignal, type Signal } from '@fictjs/runtime/advanced'\n\n/** Function type for bound methods */\ntype AnyFn = (...args: unknown[]) => unknown\n\n/** Cache entry for bound methods to preserve identity */\ninterface BoundMethodEntry {\n ref: AnyFn\n bound: AnyFn\n}\n\n/** Type for objects with indexable properties */\ntype IndexableObject = Record<string | symbol, unknown>\n\n/** Symbol to mark proxies and prevent double-wrapping */\nconst IS_STORE_PROXY = Symbol('fict-store-proxy')\n\n/** WeakSet to track raw objects that have been proxied (for reverse lookup) */\nconst RAW_TO_PROXY = new WeakMap<object, object>()\n\n/** Cache of proxied objects to avoid duplicate proxies */\nconst PROXY_CACHE = new WeakMap<object, unknown>()\n\n/** Dev mode detection */\nconst isDev =\n typeof __DEV__ !== 'undefined'\n ? __DEV__\n : typeof process === 'undefined' || process.env?.NODE_ENV !== 'production'\n\n/** Track if we've warned about direct mutation for a target object */\nconst MUTATION_WARNED = new WeakSet<object>()\n\n/** Properties to skip for direct mutation warning (built-in/internal properties) */\nconst SKIP_MUTATION_WARNING_PROPS: (string | symbol)[] = [\n 'constructor',\n 'prototype',\n '__proto__',\n 'toString',\n 'valueOf',\n 'toLocaleString',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n Symbol.toStringTag,\n Symbol.iterator,\n Symbol.toPrimitive,\n]\n\n/** Cache of signals per object property */\nconst SIGNAL_CACHE = new WeakMap<object, Record<string | symbol, Signal<unknown>>>()\n\n/** Cache of bound methods to preserve function identity across reads */\nconst BOUND_METHOD_CACHE = new WeakMap<object, Map<string | symbol, BoundMethodEntry>>()\n\n/** Special key for tracking iteration (Object.keys, for-in, etc.) */\nconst ITERATE_KEY = Symbol('iterate')\n\n/**\n * Get or create a signal for a specific property on a target object.\n * @internal\n */\nfunction getSignal(target: object, prop: string | symbol): Signal<unknown> {\n let signals = SIGNAL_CACHE.get(target)\n if (!signals) {\n signals = {}\n SIGNAL_CACHE.set(target, signals)\n }\n if (!signals[prop]) {\n const initial = prop === ITERATE_KEY ? 0 : (target as IndexableObject)[prop]\n signals[prop] = createSignal(initial)\n }\n return signals[prop]\n}\n\n/**\n * Trigger iteration signal to notify consumers that keys have changed.\n * @internal\n */\nfunction triggerIteration(target: object): void {\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals[ITERATE_KEY]) {\n const current = signals[ITERATE_KEY]() as number\n signals[ITERATE_KEY](current + 1)\n }\n}\n\n/**\n * Create a deep reactive store using Proxy.\n *\n * Unlike `$state` (which is shallow and compiler-transformed), `$store` provides:\n * - **Deep reactivity**: Nested objects are automatically wrapped in proxies\n * - **Direct mutation**: Modify properties directly without spread operators\n * - **Path-level tracking**: Only components reading changed paths re-render\n *\n * @param initialValue - The initial object to make reactive\n * @returns A reactive proxy of the object\n *\n * @example\n * ```tsx\n * import { $store } from 'fict'\n *\n * const form = $store({\n * user: { name: '', email: '' },\n * settings: { theme: 'light' }\n * })\n *\n * // Direct mutation works\n * form.user.name = 'Alice'\n *\n * // In JSX - only updates when form.user.name changes\n * <input value={form.user.name} />\n * ```\n *\n * @public\n */\nexport function $store<T extends object>(initialValue: T): T {\n if (typeof initialValue !== 'object' || initialValue === null) {\n return initialValue\n }\n\n // Prevent double-wrapping - if already a store proxy, return as-is\n if ((initialValue as IndexableObject)[IS_STORE_PROXY]) {\n return initialValue\n }\n\n // Check if this object was already wrapped (reverse lookup)\n if (RAW_TO_PROXY.has(initialValue)) {\n return RAW_TO_PROXY.get(initialValue) as T\n }\n\n if (PROXY_CACHE.has(initialValue)) {\n return PROXY_CACHE.get(initialValue) as T\n }\n\n const proxy = new Proxy(initialValue, {\n get(target, prop, receiver) {\n // Return true for IS_STORE_PROXY to identify this as a store proxy\n if (prop === IS_STORE_PROXY) {\n return true\n }\n\n // Always touch the signal so reference changes to this property are tracked,\n // even if the value is an object we proxy further.\n const signal = getSignal(target, prop)\n const trackedValue = signal()\n\n const currentValue = Reflect.get(target, prop, receiver ?? proxy)\n\n // Remove \"read-time write\" - direct mutation is now undefined behavior\n // In dev mode, warn once per object if we detect the underlying object was mutated directly\n if (\n isDev &&\n currentValue !== trackedValue &&\n !SKIP_MUTATION_WARNING_PROPS.includes(prop) &&\n !MUTATION_WARNED.has(target)\n ) {\n MUTATION_WARNED.add(target)\n console.warn(`[fict] Use $store for ${String(prop)}.`)\n }\n\n if (typeof currentValue === 'function') {\n let boundMethods = BOUND_METHOD_CACHE.get(target)\n if (!boundMethods) {\n boundMethods = new Map()\n BOUND_METHOD_CACHE.set(target, boundMethods)\n }\n const cached = boundMethods.get(prop)\n if (cached && cached.ref === currentValue) {\n return cached.bound\n }\n\n const bound = (currentValue as AnyFn).bind(receiver ?? proxy)\n boundMethods.set(prop, { ref: currentValue as AnyFn, bound })\n return bound\n }\n {\n const boundMethods = BOUND_METHOD_CACHE.get(target)\n if (boundMethods && boundMethods.has(prop)) {\n boundMethods.delete(prop)\n if (boundMethods.size === 0) {\n BOUND_METHOD_CACHE.delete(target)\n }\n }\n }\n\n // If the value is an object/array, we recursively wrap it in a store\n if (typeof currentValue === 'object' && currentValue !== null) {\n return $store(currentValue as Record<string, unknown>)\n }\n\n // For primitives (and functions), we return the signal value (which tracks the read)\n return currentValue\n },\n\n set(target, prop, newValue, receiver) {\n const oldLength = Array.isArray(target) && prop === 'length' ? target.length : undefined\n const oldValue = Reflect.get(target, prop, receiver)\n const hadKey = Object.prototype.hasOwnProperty.call(target, prop)\n\n // If value hasn't changed, do nothing\n if (oldValue === newValue && hadKey) {\n return true\n }\n\n const result = Reflect.set(target, prop, newValue, receiver)\n\n // IMPORTANT: Clear bound method cache BEFORE updating the signal\n const boundMethods = BOUND_METHOD_CACHE.get(target)\n if (boundMethods && boundMethods.has(prop)) {\n boundMethods.delete(prop)\n if (boundMethods.size === 0) {\n BOUND_METHOD_CACHE.delete(target)\n }\n }\n\n // Update the signal if it exists\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals[prop]) {\n signals[prop](newValue)\n }\n\n // If new property, trigger iteration update\n if (!hadKey) {\n triggerIteration(target)\n }\n\n // Ensure array length subscribers are notified even if the native push/pop\n // doesn't trigger a separate set trap for \"length\" (defensive).\n if (Array.isArray(target) && prop !== 'length') {\n if (signals && signals.length) {\n signals.length(target.length)\n }\n }\n\n // If it's an array and length changed implicitly, we might need to handle it.\n if (Array.isArray(target) && prop === 'length') {\n const nextLength = target.length\n if (typeof oldLength === 'number' && nextLength < oldLength) {\n if (signals) {\n for (let i = nextLength; i < oldLength; i += 1) {\n const key = String(i)\n if (signals[key]) {\n signals[key](undefined)\n }\n }\n }\n }\n triggerIteration(target)\n }\n\n return result\n },\n\n deleteProperty(target, prop) {\n const hadKey = Object.prototype.hasOwnProperty.call(target, prop)\n const result = Reflect.deleteProperty(target, prop)\n\n if (result && hadKey) {\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals[prop]) {\n signals[prop](undefined)\n }\n\n // Clear bound method cache\n const boundMethods = BOUND_METHOD_CACHE.get(target)\n if (boundMethods && boundMethods.has(prop)) {\n boundMethods.delete(prop)\n if (boundMethods.size === 0) {\n BOUND_METHOD_CACHE.delete(target)\n }\n }\n\n triggerIteration(target)\n }\n\n return result\n },\n\n ownKeys(target) {\n getSignal(target, ITERATE_KEY)()\n return Reflect.ownKeys(target)\n },\n\n has(target, prop) {\n getSignal(target, prop)()\n return Reflect.has(target, prop)\n },\n })\n\n PROXY_CACHE.set(initialValue, proxy)\n // Register reverse lookup for double-wrap prevention\n RAW_TO_PROXY.set(initialValue, proxy)\n return proxy\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// src/macro-diagnostics.ts
|
|
2
|
+
function createUncompiledMacroError(macroName) {
|
|
3
|
+
const isDev = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
4
|
+
return new Error(isDev ? `${macroName}() compile-only.` : "FICT_E_UNCOMPILED");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export { createUncompiledMacroError };
|
|
8
|
+
//# sourceMappingURL=chunk-TKWIPOL2.js.map
|
|
9
|
+
//# sourceMappingURL=chunk-TKWIPOL2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/macro-diagnostics.ts"],"names":[],"mappings":";AAAO,SAAS,2BAA2B,SAAA,EAAwC;AACjF,EAAA,MAAM,KAAA,GACJ,OAAO,OAAA,KAAY,WAAA,GACf,OAAA,GACA,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK,QAAA,KAAa,YAAA;AAClE,EAAA,OAAO,IAAI,KAAA,CAAM,KAAA,GAAQ,CAAA,EAAG,SAAS,qBAAqB,mBAAmB,CAAA;AAC/E","file":"chunk-TKWIPOL2.js","sourcesContent":["export function createUncompiledMacroError(macroName: '$state' | '$effect'): Error {\n const isDev =\n typeof __DEV__ !== 'undefined'\n ? __DEV__\n : typeof process === 'undefined' || process.env?.NODE_ENV !== 'production'\n return new Error(isDev ? `${macroName}() compile-only.` : 'FICT_E_UNCOMPILED')\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -3,13 +3,17 @@
|
|
|
3
3
|
var runtime = require('@fictjs/runtime');
|
|
4
4
|
var advanced = require('@fictjs/runtime/advanced');
|
|
5
5
|
|
|
6
|
-
// src/
|
|
6
|
+
// src/macro-diagnostics.ts
|
|
7
|
+
function createUncompiledMacroError(macroName) {
|
|
8
|
+
const isDev2 = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
9
|
+
return new Error(isDev2 ? `${macroName}() compile-only.` : "FICT_E_UNCOMPILED");
|
|
10
|
+
}
|
|
7
11
|
var IS_STORE_PROXY = Symbol("fict-store-proxy");
|
|
8
12
|
var RAW_TO_PROXY = /* @__PURE__ */ new WeakMap();
|
|
9
13
|
var PROXY_CACHE = /* @__PURE__ */ new WeakMap();
|
|
10
14
|
var isDev = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
11
|
-
var MUTATION_WARNED = /* @__PURE__ */ new
|
|
12
|
-
var SKIP_MUTATION_WARNING_PROPS =
|
|
15
|
+
var MUTATION_WARNED = /* @__PURE__ */ new WeakSet();
|
|
16
|
+
var SKIP_MUTATION_WARNING_PROPS = [
|
|
13
17
|
"constructor",
|
|
14
18
|
"prototype",
|
|
15
19
|
"__proto__",
|
|
@@ -22,7 +26,7 @@ var SKIP_MUTATION_WARNING_PROPS = /* @__PURE__ */ new Set([
|
|
|
22
26
|
Symbol.toStringTag,
|
|
23
27
|
Symbol.iterator,
|
|
24
28
|
Symbol.toPrimitive
|
|
25
|
-
]
|
|
29
|
+
];
|
|
26
30
|
var SIGNAL_CACHE = /* @__PURE__ */ new WeakMap();
|
|
27
31
|
var BOUND_METHOD_CACHE = /* @__PURE__ */ new WeakMap();
|
|
28
32
|
var ITERATE_KEY = Symbol("iterate");
|
|
@@ -66,18 +70,9 @@ function $store(initialValue) {
|
|
|
66
70
|
const signal = getSignal(target, prop);
|
|
67
71
|
const trackedValue = signal();
|
|
68
72
|
const currentValue = Reflect.get(target, prop, receiver ?? proxy);
|
|
69
|
-
if (isDev && currentValue !== trackedValue && !SKIP_MUTATION_WARNING_PROPS.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
warnedProps = /* @__PURE__ */ new Set();
|
|
73
|
-
MUTATION_WARNED.set(target, warnedProps);
|
|
74
|
-
}
|
|
75
|
-
if (!warnedProps.has(prop)) {
|
|
76
|
-
warnedProps.add(prop);
|
|
77
|
-
console.warn(
|
|
78
|
-
`[fict] Direct mutation detected for "${String(prop)}"; mutate via $store proxy.`
|
|
79
|
-
);
|
|
80
|
-
}
|
|
73
|
+
if (isDev && currentValue !== trackedValue && !SKIP_MUTATION_WARNING_PROPS.includes(prop) && !MUTATION_WARNED.has(target)) {
|
|
74
|
+
MUTATION_WARNED.add(target);
|
|
75
|
+
console.warn(`[fict] Use $store for ${String(prop)}.`);
|
|
81
76
|
}
|
|
82
77
|
if (typeof currentValue === "function") {
|
|
83
78
|
let boundMethods = BOUND_METHOD_CACHE.get(target);
|
|
@@ -130,20 +125,18 @@ function $store(initialValue) {
|
|
|
130
125
|
triggerIteration(target);
|
|
131
126
|
}
|
|
132
127
|
if (Array.isArray(target) && prop !== "length") {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
signals2.length(target.length);
|
|
128
|
+
if (signals && signals.length) {
|
|
129
|
+
signals.length(target.length);
|
|
136
130
|
}
|
|
137
131
|
}
|
|
138
132
|
if (Array.isArray(target) && prop === "length") {
|
|
139
133
|
const nextLength = target.length;
|
|
140
134
|
if (typeof oldLength === "number" && nextLength < oldLength) {
|
|
141
|
-
|
|
142
|
-
if (signals2) {
|
|
135
|
+
if (signals) {
|
|
143
136
|
for (let i = nextLength; i < oldLength; i += 1) {
|
|
144
137
|
const key = String(i);
|
|
145
|
-
if (
|
|
146
|
-
|
|
138
|
+
if (signals[key]) {
|
|
139
|
+
signals[key](void 0);
|
|
147
140
|
}
|
|
148
141
|
}
|
|
149
142
|
}
|
|
@@ -187,10 +180,10 @@ function $store(initialValue) {
|
|
|
187
180
|
|
|
188
181
|
// src/index.ts
|
|
189
182
|
function $state(_initialValue) {
|
|
190
|
-
throw
|
|
183
|
+
throw createUncompiledMacroError("$state");
|
|
191
184
|
}
|
|
192
185
|
function $effect(_fn) {
|
|
193
|
-
throw
|
|
186
|
+
throw createUncompiledMacroError("$effect");
|
|
194
187
|
}
|
|
195
188
|
|
|
196
189
|
Object.defineProperty(exports, "$memo", {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/store.ts","../src/index.ts"],"names":["createSignal","signals"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @fileoverview Deep reactive store implementation for Fict.\n *\n * $store creates a deeply reactive proxy that tracks property access at the path level.\n * Unlike $state (which is shallow), $store allows direct mutation of nested properties.\n *\n * @example\n * ```typescript\n * const user = $store({ name: 'Alice', address: { city: 'London' } })\n * user.address.city = 'Paris' // Fine-grained reactive update\n * ```\n */\n\nimport { createSignal, type Signal } from '@fictjs/runtime/advanced'\n\n/** Function type for bound methods */\ntype AnyFn = (...args: unknown[]) => unknown\n\n/** Cache entry for bound methods to preserve identity */\ninterface BoundMethodEntry {\n ref: AnyFn\n bound: AnyFn\n}\n\n/** Type for objects with indexable properties */\ntype IndexableObject = Record<string | symbol, unknown>\n\n/** Symbol to mark proxies and prevent double-wrapping */\nconst IS_STORE_PROXY = Symbol('fict-store-proxy')\n\n/** WeakSet to track raw objects that have been proxied (for reverse lookup) */\nconst RAW_TO_PROXY = new WeakMap<object, object>()\n\n/** Cache of proxied objects to avoid duplicate proxies */\nconst PROXY_CACHE = new WeakMap<object, unknown>()\n\n/** Dev mode detection */\nconst isDev =\n typeof __DEV__ !== 'undefined'\n ? __DEV__\n : typeof process === 'undefined' || process.env?.NODE_ENV !== 'production'\n\n/** Track if we've warned about direct mutation for a specific target+property */\nconst MUTATION_WARNED = new WeakMap<object, Set<string | symbol>>()\n\n/** Properties to skip for direct mutation warning (built-in/internal properties) */\nconst SKIP_MUTATION_WARNING_PROPS = new Set<string | symbol>([\n 'constructor',\n 'prototype',\n '__proto__',\n 'toString',\n 'valueOf',\n 'toLocaleString',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n Symbol.toStringTag,\n Symbol.iterator,\n Symbol.toPrimitive,\n])\n\n/** Cache of signals per object property */\nconst SIGNAL_CACHE = new WeakMap<object, Record<string | symbol, Signal<unknown>>>()\n\n/** Cache of bound methods to preserve function identity across reads */\nconst BOUND_METHOD_CACHE = new WeakMap<object, Map<string | symbol, BoundMethodEntry>>()\n\n/** Special key for tracking iteration (Object.keys, for-in, etc.) */\nconst ITERATE_KEY = Symbol('iterate')\n\n/**\n * Get or create a signal for a specific property on a target object.\n * @internal\n */\nfunction getSignal(target: object, prop: string | symbol): Signal<unknown> {\n let signals = SIGNAL_CACHE.get(target)\n if (!signals) {\n signals = {}\n SIGNAL_CACHE.set(target, signals)\n }\n if (!signals[prop]) {\n const initial = prop === ITERATE_KEY ? 0 : (target as IndexableObject)[prop]\n signals[prop] = createSignal(initial)\n }\n return signals[prop]\n}\n\n/**\n * Trigger iteration signal to notify consumers that keys have changed.\n * @internal\n */\nfunction triggerIteration(target: object): void {\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals[ITERATE_KEY]) {\n const current = signals[ITERATE_KEY]() as number\n signals[ITERATE_KEY](current + 1)\n }\n}\n\n/**\n * Create a deep reactive store using Proxy.\n *\n * Unlike `$state` (which is shallow and compiler-transformed), `$store` provides:\n * - **Deep reactivity**: Nested objects are automatically wrapped in proxies\n * - **Direct mutation**: Modify properties directly without spread operators\n * - **Path-level tracking**: Only components reading changed paths re-render\n *\n * @param initialValue - The initial object to make reactive\n * @returns A reactive proxy of the object\n *\n * @example\n * ```tsx\n * import { $store } from 'fict'\n *\n * const form = $store({\n * user: { name: '', email: '' },\n * settings: { theme: 'light' }\n * })\n *\n * // Direct mutation works\n * form.user.name = 'Alice'\n *\n * // In JSX - only updates when form.user.name changes\n * <input value={form.user.name} />\n * ```\n *\n * @public\n */\nexport function $store<T extends object>(initialValue: T): T {\n if (typeof initialValue !== 'object' || initialValue === null) {\n return initialValue\n }\n\n // Prevent double-wrapping - if already a store proxy, return as-is\n if ((initialValue as IndexableObject)[IS_STORE_PROXY]) {\n return initialValue\n }\n\n // Check if this object was already wrapped (reverse lookup)\n if (RAW_TO_PROXY.has(initialValue)) {\n return RAW_TO_PROXY.get(initialValue) as T\n }\n\n if (PROXY_CACHE.has(initialValue)) {\n return PROXY_CACHE.get(initialValue) as T\n }\n\n const proxy = new Proxy(initialValue, {\n get(target, prop, receiver) {\n // Return true for IS_STORE_PROXY to identify this as a store proxy\n if (prop === IS_STORE_PROXY) {\n return true\n }\n\n // Always touch the signal so reference changes to this property are tracked,\n // even if the value is an object we proxy further.\n const signal = getSignal(target, prop)\n const trackedValue = signal()\n\n const currentValue = Reflect.get(target, prop, receiver ?? proxy)\n\n // Remove \"read-time write\" - direct mutation is now undefined behavior\n // In dev mode, warn once per property if we detect the underlying object was mutated directly\n if (isDev && currentValue !== trackedValue && !SKIP_MUTATION_WARNING_PROPS.has(prop)) {\n let warnedProps = MUTATION_WARNED.get(target)\n if (!warnedProps) {\n warnedProps = new Set()\n MUTATION_WARNED.set(target, warnedProps)\n }\n if (!warnedProps.has(prop)) {\n warnedProps.add(prop)\n console.warn(\n `[fict] Direct mutation detected for \"${String(prop)}\"; mutate via $store proxy.`,\n )\n }\n }\n\n if (typeof currentValue === 'function') {\n let boundMethods = BOUND_METHOD_CACHE.get(target)\n if (!boundMethods) {\n boundMethods = new Map()\n BOUND_METHOD_CACHE.set(target, boundMethods)\n }\n const cached = boundMethods.get(prop)\n if (cached && cached.ref === currentValue) {\n return cached.bound\n }\n\n const bound = (currentValue as AnyFn).bind(receiver ?? proxy)\n boundMethods.set(prop, { ref: currentValue as AnyFn, bound })\n return bound\n }\n {\n const boundMethods = BOUND_METHOD_CACHE.get(target)\n if (boundMethods && boundMethods.has(prop)) {\n boundMethods.delete(prop)\n if (boundMethods.size === 0) {\n BOUND_METHOD_CACHE.delete(target)\n }\n }\n }\n\n // If the value is an object/array, we recursively wrap it in a store\n if (typeof currentValue === 'object' && currentValue !== null) {\n return $store(currentValue as Record<string, unknown>)\n }\n\n // For primitives (and functions), we return the signal value (which tracks the read)\n return currentValue\n },\n\n set(target, prop, newValue, receiver) {\n const oldLength = Array.isArray(target) && prop === 'length' ? target.length : undefined\n const oldValue = Reflect.get(target, prop, receiver)\n const hadKey = Object.prototype.hasOwnProperty.call(target, prop)\n\n // If value hasn't changed, do nothing\n if (oldValue === newValue && hadKey) {\n return true\n }\n\n const result = Reflect.set(target, prop, newValue, receiver)\n\n // IMPORTANT: Clear bound method cache BEFORE updating the signal\n const boundMethods = BOUND_METHOD_CACHE.get(target)\n if (boundMethods && boundMethods.has(prop)) {\n boundMethods.delete(prop)\n if (boundMethods.size === 0) {\n BOUND_METHOD_CACHE.delete(target)\n }\n }\n\n // Update the signal if it exists\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals[prop]) {\n signals[prop](newValue)\n }\n\n // If new property, trigger iteration update\n if (!hadKey) {\n triggerIteration(target)\n }\n\n // Ensure array length subscribers are notified even if the native push/pop\n // doesn't trigger a separate set trap for \"length\" (defensive).\n if (Array.isArray(target) && prop !== 'length') {\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals.length) {\n signals.length(target.length)\n }\n }\n\n // If it's an array and length changed implicitly, we might need to handle it.\n if (Array.isArray(target) && prop === 'length') {\n const nextLength = target.length\n if (typeof oldLength === 'number' && nextLength < oldLength) {\n const signals = SIGNAL_CACHE.get(target)\n if (signals) {\n for (let i = nextLength; i < oldLength; i += 1) {\n const key = String(i)\n if (signals[key]) {\n signals[key](undefined)\n }\n }\n }\n }\n triggerIteration(target)\n }\n\n return result\n },\n\n deleteProperty(target, prop) {\n const hadKey = Object.prototype.hasOwnProperty.call(target, prop)\n const result = Reflect.deleteProperty(target, prop)\n\n if (result && hadKey) {\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals[prop]) {\n signals[prop](undefined)\n }\n\n // Clear bound method cache\n const boundMethods = BOUND_METHOD_CACHE.get(target)\n if (boundMethods && boundMethods.has(prop)) {\n boundMethods.delete(prop)\n if (boundMethods.size === 0) {\n BOUND_METHOD_CACHE.delete(target)\n }\n }\n\n triggerIteration(target)\n }\n\n return result\n },\n\n ownKeys(target) {\n getSignal(target, ITERATE_KEY)()\n return Reflect.ownKeys(target)\n },\n\n has(target, prop) {\n getSignal(target, prop)()\n return Reflect.has(target, prop)\n },\n })\n\n PROXY_CACHE.set(initialValue, proxy)\n // Register reverse lookup for double-wrap prevention\n RAW_TO_PROXY.set(initialValue, proxy)\n return proxy\n}\n","/**\n * @fileoverview Fict Framework - Complete API\n *\n * This is the main entry point for the Fict framework.\n *\n * ## Recommended Import Pattern (v1.0+)\n *\n * ```typescript\n * // Core public API (most users need only this)\n * // Use $state in components (compiler-transformed)\n * // Use $store for cross-component shared state\n * import { $store, render } from 'fict'\n *\n * // Async utilities\n * import { resource, lazy } from 'fict/plus'\n *\n * // Advanced APIs (escape hatches, library authors)\n * import { createSignal, createContext, createScope } from 'fict/advanced'\n * ```\n *\n * ## State Management Guide\n *\n * | Use Case | API |\n * |----------|-----|\n * | Component-local state | `$state` (compiler-transformed) |\n * | Derived values / side effects | JS + auto-derived + `$effect` |\n * | Cross-component (large objects, deep mutation) | `$store` |\n * | Cross-component (scalar/lightweight, library-level) | `createSignal` (advanced) |\n * | Cross-component (subtree scope, SSR isolation) | `Context` (advanced) |\n *\n * @public\n * @packageDocumentation\n */\n\n// Re-export everything from runtime\nexport * from '@fictjs/runtime'\n\n// Re-export commonly used advanced APIs for convenience\nexport { createSelector, createScope, runInScope } from '@fictjs/runtime/advanced'\n\n// ============================================================================\n// Convenience Aliases\n// ============================================================================\n\n/**\n * Alias for createMemo.\n * Creates a memoized value that only recomputes when dependencies change.\n *\n * @example\n * ```tsx\n * const fullName = $memo(() => firstName + ' ' + lastName)\n * ```\n *\n * @public\n */\nexport { createMemo as $memo } from '@fictjs/runtime'\n\n// ============================================================================\n// Deep Reactive Store (Proxy-based)\n// ============================================================================\n\n/**\n * Create a deep reactive store using Proxy.\n * Unlike createStore, $store allows direct mutation.\n *\n * @example\n * ```tsx\n * const user = $store({ name: 'Alice', address: { city: 'Beijing' } })\n * user.name = 'Bob' // Reactive update\n * user.address.city = 'Shanghai' // Deep reactive\n * ```\n *\n * @public\n */\nexport { $store } from './store'\n\n// ============================================================================\n// Compiler Macros (transformed at compile time)\n// ============================================================================\n\n/**\n * Compiler macro for reactive state.\n * This is transformed at compile time and should never be called at runtime.\n *\n * @example\n * ```tsx\n * let count = $state(0)\n * count++ // Reactive update\n * ```\n *\n * @public\n */\nexport function $state<T>(_initialValue: T): T {\n // This function is never called at runtime - the compiler transforms it\n throw new Error('$state() is a compiler macro and should be transformed at compile time')\n}\n\n/**\n * Compiler macro for reactive effects.\n * This is transformed at compile time and should never be called at runtime.\n *\n * @example\n * ```tsx\n * $effect(() => {\n * console.log('count changed:', count)\n * })\n * ```\n *\n * @public\n */\nexport function $effect(_fn: () => void | (() => void)): void {\n // This function is never called at runtime - the compiler transforms it\n throw new Error('$effect() is a compiler macro and should be transformed at compile time')\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/macro-diagnostics.ts","../src/store.ts","../src/index.ts"],"names":["isDev","createSignal"],"mappings":"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","file":"index.cjs","sourcesContent":["export function createUncompiledMacroError(macroName: '$state' | '$effect'): Error {\n const isDev =\n typeof __DEV__ !== 'undefined'\n ? __DEV__\n : typeof process === 'undefined' || process.env?.NODE_ENV !== 'production'\n return new Error(isDev ? `${macroName}() compile-only.` : 'FICT_E_UNCOMPILED')\n}\n","/**\n * @fileoverview Deep reactive store implementation for Fict.\n *\n * $store creates a deeply reactive proxy that tracks property access at the path level.\n * Unlike $state (which is shallow), $store allows direct mutation of nested properties.\n *\n * @example\n * ```typescript\n * const user = $store({ name: 'Alice', address: { city: 'London' } })\n * user.address.city = 'Paris' // Fine-grained reactive update\n * ```\n */\n\nimport { createSignal, type Signal } from '@fictjs/runtime/advanced'\n\n/** Function type for bound methods */\ntype AnyFn = (...args: unknown[]) => unknown\n\n/** Cache entry for bound methods to preserve identity */\ninterface BoundMethodEntry {\n ref: AnyFn\n bound: AnyFn\n}\n\n/** Type for objects with indexable properties */\ntype IndexableObject = Record<string | symbol, unknown>\n\n/** Symbol to mark proxies and prevent double-wrapping */\nconst IS_STORE_PROXY = Symbol('fict-store-proxy')\n\n/** WeakSet to track raw objects that have been proxied (for reverse lookup) */\nconst RAW_TO_PROXY = new WeakMap<object, object>()\n\n/** Cache of proxied objects to avoid duplicate proxies */\nconst PROXY_CACHE = new WeakMap<object, unknown>()\n\n/** Dev mode detection */\nconst isDev =\n typeof __DEV__ !== 'undefined'\n ? __DEV__\n : typeof process === 'undefined' || process.env?.NODE_ENV !== 'production'\n\n/** Track if we've warned about direct mutation for a target object */\nconst MUTATION_WARNED = new WeakSet<object>()\n\n/** Properties to skip for direct mutation warning (built-in/internal properties) */\nconst SKIP_MUTATION_WARNING_PROPS: (string | symbol)[] = [\n 'constructor',\n 'prototype',\n '__proto__',\n 'toString',\n 'valueOf',\n 'toLocaleString',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n Symbol.toStringTag,\n Symbol.iterator,\n Symbol.toPrimitive,\n]\n\n/** Cache of signals per object property */\nconst SIGNAL_CACHE = new WeakMap<object, Record<string | symbol, Signal<unknown>>>()\n\n/** Cache of bound methods to preserve function identity across reads */\nconst BOUND_METHOD_CACHE = new WeakMap<object, Map<string | symbol, BoundMethodEntry>>()\n\n/** Special key for tracking iteration (Object.keys, for-in, etc.) */\nconst ITERATE_KEY = Symbol('iterate')\n\n/**\n * Get or create a signal for a specific property on a target object.\n * @internal\n */\nfunction getSignal(target: object, prop: string | symbol): Signal<unknown> {\n let signals = SIGNAL_CACHE.get(target)\n if (!signals) {\n signals = {}\n SIGNAL_CACHE.set(target, signals)\n }\n if (!signals[prop]) {\n const initial = prop === ITERATE_KEY ? 0 : (target as IndexableObject)[prop]\n signals[prop] = createSignal(initial)\n }\n return signals[prop]\n}\n\n/**\n * Trigger iteration signal to notify consumers that keys have changed.\n * @internal\n */\nfunction triggerIteration(target: object): void {\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals[ITERATE_KEY]) {\n const current = signals[ITERATE_KEY]() as number\n signals[ITERATE_KEY](current + 1)\n }\n}\n\n/**\n * Create a deep reactive store using Proxy.\n *\n * Unlike `$state` (which is shallow and compiler-transformed), `$store` provides:\n * - **Deep reactivity**: Nested objects are automatically wrapped in proxies\n * - **Direct mutation**: Modify properties directly without spread operators\n * - **Path-level tracking**: Only components reading changed paths re-render\n *\n * @param initialValue - The initial object to make reactive\n * @returns A reactive proxy of the object\n *\n * @example\n * ```tsx\n * import { $store } from 'fict'\n *\n * const form = $store({\n * user: { name: '', email: '' },\n * settings: { theme: 'light' }\n * })\n *\n * // Direct mutation works\n * form.user.name = 'Alice'\n *\n * // In JSX - only updates when form.user.name changes\n * <input value={form.user.name} />\n * ```\n *\n * @public\n */\nexport function $store<T extends object>(initialValue: T): T {\n if (typeof initialValue !== 'object' || initialValue === null) {\n return initialValue\n }\n\n // Prevent double-wrapping - if already a store proxy, return as-is\n if ((initialValue as IndexableObject)[IS_STORE_PROXY]) {\n return initialValue\n }\n\n // Check if this object was already wrapped (reverse lookup)\n if (RAW_TO_PROXY.has(initialValue)) {\n return RAW_TO_PROXY.get(initialValue) as T\n }\n\n if (PROXY_CACHE.has(initialValue)) {\n return PROXY_CACHE.get(initialValue) as T\n }\n\n const proxy = new Proxy(initialValue, {\n get(target, prop, receiver) {\n // Return true for IS_STORE_PROXY to identify this as a store proxy\n if (prop === IS_STORE_PROXY) {\n return true\n }\n\n // Always touch the signal so reference changes to this property are tracked,\n // even if the value is an object we proxy further.\n const signal = getSignal(target, prop)\n const trackedValue = signal()\n\n const currentValue = Reflect.get(target, prop, receiver ?? proxy)\n\n // Remove \"read-time write\" - direct mutation is now undefined behavior\n // In dev mode, warn once per object if we detect the underlying object was mutated directly\n if (\n isDev &&\n currentValue !== trackedValue &&\n !SKIP_MUTATION_WARNING_PROPS.includes(prop) &&\n !MUTATION_WARNED.has(target)\n ) {\n MUTATION_WARNED.add(target)\n console.warn(`[fict] Use $store for ${String(prop)}.`)\n }\n\n if (typeof currentValue === 'function') {\n let boundMethods = BOUND_METHOD_CACHE.get(target)\n if (!boundMethods) {\n boundMethods = new Map()\n BOUND_METHOD_CACHE.set(target, boundMethods)\n }\n const cached = boundMethods.get(prop)\n if (cached && cached.ref === currentValue) {\n return cached.bound\n }\n\n const bound = (currentValue as AnyFn).bind(receiver ?? proxy)\n boundMethods.set(prop, { ref: currentValue as AnyFn, bound })\n return bound\n }\n {\n const boundMethods = BOUND_METHOD_CACHE.get(target)\n if (boundMethods && boundMethods.has(prop)) {\n boundMethods.delete(prop)\n if (boundMethods.size === 0) {\n BOUND_METHOD_CACHE.delete(target)\n }\n }\n }\n\n // If the value is an object/array, we recursively wrap it in a store\n if (typeof currentValue === 'object' && currentValue !== null) {\n return $store(currentValue as Record<string, unknown>)\n }\n\n // For primitives (and functions), we return the signal value (which tracks the read)\n return currentValue\n },\n\n set(target, prop, newValue, receiver) {\n const oldLength = Array.isArray(target) && prop === 'length' ? target.length : undefined\n const oldValue = Reflect.get(target, prop, receiver)\n const hadKey = Object.prototype.hasOwnProperty.call(target, prop)\n\n // If value hasn't changed, do nothing\n if (oldValue === newValue && hadKey) {\n return true\n }\n\n const result = Reflect.set(target, prop, newValue, receiver)\n\n // IMPORTANT: Clear bound method cache BEFORE updating the signal\n const boundMethods = BOUND_METHOD_CACHE.get(target)\n if (boundMethods && boundMethods.has(prop)) {\n boundMethods.delete(prop)\n if (boundMethods.size === 0) {\n BOUND_METHOD_CACHE.delete(target)\n }\n }\n\n // Update the signal if it exists\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals[prop]) {\n signals[prop](newValue)\n }\n\n // If new property, trigger iteration update\n if (!hadKey) {\n triggerIteration(target)\n }\n\n // Ensure array length subscribers are notified even if the native push/pop\n // doesn't trigger a separate set trap for \"length\" (defensive).\n if (Array.isArray(target) && prop !== 'length') {\n if (signals && signals.length) {\n signals.length(target.length)\n }\n }\n\n // If it's an array and length changed implicitly, we might need to handle it.\n if (Array.isArray(target) && prop === 'length') {\n const nextLength = target.length\n if (typeof oldLength === 'number' && nextLength < oldLength) {\n if (signals) {\n for (let i = nextLength; i < oldLength; i += 1) {\n const key = String(i)\n if (signals[key]) {\n signals[key](undefined)\n }\n }\n }\n }\n triggerIteration(target)\n }\n\n return result\n },\n\n deleteProperty(target, prop) {\n const hadKey = Object.prototype.hasOwnProperty.call(target, prop)\n const result = Reflect.deleteProperty(target, prop)\n\n if (result && hadKey) {\n const signals = SIGNAL_CACHE.get(target)\n if (signals && signals[prop]) {\n signals[prop](undefined)\n }\n\n // Clear bound method cache\n const boundMethods = BOUND_METHOD_CACHE.get(target)\n if (boundMethods && boundMethods.has(prop)) {\n boundMethods.delete(prop)\n if (boundMethods.size === 0) {\n BOUND_METHOD_CACHE.delete(target)\n }\n }\n\n triggerIteration(target)\n }\n\n return result\n },\n\n ownKeys(target) {\n getSignal(target, ITERATE_KEY)()\n return Reflect.ownKeys(target)\n },\n\n has(target, prop) {\n getSignal(target, prop)()\n return Reflect.has(target, prop)\n },\n })\n\n PROXY_CACHE.set(initialValue, proxy)\n // Register reverse lookup for double-wrap prevention\n RAW_TO_PROXY.set(initialValue, proxy)\n return proxy\n}\n","/**\n * @fileoverview Fict Framework - Complete API\n *\n * This is the main entry point for the Fict framework.\n *\n * ## Recommended Import Pattern (v1.0+)\n *\n * ```typescript\n * // Core public API (most users need only this)\n * // Use $state in components (compiler-transformed)\n * // Use $store for cross-component shared state\n * import { $store, render } from 'fict'\n *\n * // Async utilities\n * import { resource, lazy } from 'fict/plus'\n *\n * // Advanced APIs (escape hatches, library authors)\n * import { createSignal, createContext, createScope } from 'fict/advanced'\n * ```\n *\n * ## State Management Guide\n *\n * | Use Case | API |\n * |----------|-----|\n * | Component-local state | `$state` (compiler-transformed) |\n * | Derived values / side effects | JS + auto-derived + `$effect` |\n * | Cross-component (large objects, deep mutation) | `$store` |\n * | Cross-component (scalar/lightweight, library-level) | `createSignal` (advanced) |\n * | Cross-component (subtree scope, SSR isolation) | `Context` (advanced) |\n *\n * @public\n * @packageDocumentation\n */\n\nimport { createUncompiledMacroError } from './macro-diagnostics'\n\n// Re-export everything from runtime\nexport * from '@fictjs/runtime'\n\n// Re-export commonly used advanced APIs for convenience. Manual reactive getter\n// markers stay in `fict/advanced` so the main entrypoint remains user-facing.\nexport { createSelector, createScope, runInScope } from '@fictjs/runtime/advanced'\n\n// ============================================================================\n// Convenience Aliases\n// ============================================================================\n\n/**\n * Alias for createMemo.\n * Creates a memoized value that only recomputes when dependencies change.\n *\n * @example\n * ```tsx\n * const fullName = $memo(() => firstName + ' ' + lastName)\n * ```\n *\n * @public\n */\nexport { createMemo as $memo } from '@fictjs/runtime'\n\n// ============================================================================\n// Deep Reactive Store (Proxy-based)\n// ============================================================================\n\n/**\n * Create a deep reactive store using Proxy.\n * Unlike createStore, $store allows direct mutation.\n *\n * @example\n * ```tsx\n * const user = $store({ name: 'Alice', address: { city: 'Beijing' } })\n * user.name = 'Bob' // Reactive update\n * user.address.city = 'Shanghai' // Deep reactive\n * ```\n *\n * @public\n */\nexport { $store } from './store'\n\n// ============================================================================\n// Compiler Macros (transformed at compile time)\n// ============================================================================\n\n/**\n * Compiler macro for reactive state.\n * This is transformed at compile time and should never be called at runtime.\n *\n * @example\n * ```tsx\n * let count = $state(0)\n * count++ // Reactive update\n * ```\n *\n * @public\n */\nexport function $state<T>(_initialValue: T): T {\n // This function is never called at runtime - the compiler transforms it\n throw createUncompiledMacroError('$state')\n}\n\n/**\n * Compiler macro for reactive effects.\n * This is transformed at compile time and should never be called at runtime.\n *\n * @example\n * ```tsx\n * $effect(() => {\n * console.log('count changed:', count)\n * })\n * ```\n *\n * @public\n */\nexport function $effect(_fn: () => void | (() => void)): void {\n // This function is never called at runtime - the compiler transforms it\n throw createUncompiledMacroError('$effect')\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import { createUncompiledMacroError } from './chunk-TKWIPOL2.js';
|
|
2
|
+
export { $store } from './chunk-7CM2UZ6M.js';
|
|
2
3
|
export * from '@fictjs/runtime';
|
|
3
4
|
export { createMemo as $memo } from '@fictjs/runtime';
|
|
4
5
|
export { createScope, createSelector, runInScope } from '@fictjs/runtime/advanced';
|
|
5
6
|
|
|
6
7
|
function $state(_initialValue) {
|
|
7
|
-
throw
|
|
8
|
+
throw createUncompiledMacroError("$state");
|
|
8
9
|
}
|
|
9
10
|
function $effect(_fn) {
|
|
10
|
-
throw
|
|
11
|
+
throw createUncompiledMacroError("$effect");
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export { $effect, $state };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AA+FO,SAAS,OAAU,aAAA,EAAqB;AAE7C,EAAA,MAAM,2BAA2B,QAAQ,CAAA;AAC3C;AAeO,SAAS,QAAQ,GAAA,EAAsC;AAE5D,EAAA,MAAM,2BAA2B,SAAS,CAAA;AAC5C","file":"index.js","sourcesContent":["/**\n * @fileoverview Fict Framework - Complete API\n *\n * This is the main entry point for the Fict framework.\n *\n * ## Recommended Import Pattern (v1.0+)\n *\n * ```typescript\n * // Core public API (most users need only this)\n * // Use $state in components (compiler-transformed)\n * // Use $store for cross-component shared state\n * import { $store, render } from 'fict'\n *\n * // Async utilities\n * import { resource, lazy } from 'fict/plus'\n *\n * // Advanced APIs (escape hatches, library authors)\n * import { createSignal, createContext, createScope } from 'fict/advanced'\n * ```\n *\n * ## State Management Guide\n *\n * | Use Case | API |\n * |----------|-----|\n * | Component-local state | `$state` (compiler-transformed) |\n * | Derived values / side effects | JS + auto-derived + `$effect` |\n * | Cross-component (large objects, deep mutation) | `$store` |\n * | Cross-component (scalar/lightweight, library-level) | `createSignal` (advanced) |\n * | Cross-component (subtree scope, SSR isolation) | `Context` (advanced) |\n *\n * @public\n * @packageDocumentation\n */\n\nimport { createUncompiledMacroError } from './macro-diagnostics'\n\n// Re-export everything from runtime\nexport * from '@fictjs/runtime'\n\n// Re-export commonly used advanced APIs for convenience. Manual reactive getter\n// markers stay in `fict/advanced` so the main entrypoint remains user-facing.\nexport { createSelector, createScope, runInScope } from '@fictjs/runtime/advanced'\n\n// ============================================================================\n// Convenience Aliases\n// ============================================================================\n\n/**\n * Alias for createMemo.\n * Creates a memoized value that only recomputes when dependencies change.\n *\n * @example\n * ```tsx\n * const fullName = $memo(() => firstName + ' ' + lastName)\n * ```\n *\n * @public\n */\nexport { createMemo as $memo } from '@fictjs/runtime'\n\n// ============================================================================\n// Deep Reactive Store (Proxy-based)\n// ============================================================================\n\n/**\n * Create a deep reactive store using Proxy.\n * Unlike createStore, $store allows direct mutation.\n *\n * @example\n * ```tsx\n * const user = $store({ name: 'Alice', address: { city: 'Beijing' } })\n * user.name = 'Bob' // Reactive update\n * user.address.city = 'Shanghai' // Deep reactive\n * ```\n *\n * @public\n */\nexport { $store } from './store'\n\n// ============================================================================\n// Compiler Macros (transformed at compile time)\n// ============================================================================\n\n/**\n * Compiler macro for reactive state.\n * This is transformed at compile time and should never be called at runtime.\n *\n * @example\n * ```tsx\n * let count = $state(0)\n * count++ // Reactive update\n * ```\n *\n * @public\n */\nexport function $state<T>(_initialValue: T): T {\n // This function is never called at runtime - the compiler transforms it\n throw createUncompiledMacroError('$state')\n}\n\n/**\n * Compiler macro for reactive effects.\n * This is transformed at compile time and should never be called at runtime.\n *\n * @example\n * ```tsx\n * $effect(() => {\n * console.log('count changed:', count)\n * })\n * ```\n *\n * @public\n */\nexport function $effect(_fn: () => void | (() => void)): void {\n // This function is never called at runtime - the compiler transforms it\n throw createUncompiledMacroError('$effect')\n}\n"]}
|
package/dist/plus.cjs
CHANGED
|
@@ -8,8 +8,8 @@ var IS_STORE_PROXY = Symbol("fict-store-proxy");
|
|
|
8
8
|
var RAW_TO_PROXY = /* @__PURE__ */ new WeakMap();
|
|
9
9
|
var PROXY_CACHE = /* @__PURE__ */ new WeakMap();
|
|
10
10
|
var isDev = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
11
|
-
var MUTATION_WARNED = /* @__PURE__ */ new
|
|
12
|
-
var SKIP_MUTATION_WARNING_PROPS =
|
|
11
|
+
var MUTATION_WARNED = /* @__PURE__ */ new WeakSet();
|
|
12
|
+
var SKIP_MUTATION_WARNING_PROPS = [
|
|
13
13
|
"constructor",
|
|
14
14
|
"prototype",
|
|
15
15
|
"__proto__",
|
|
@@ -22,7 +22,7 @@ var SKIP_MUTATION_WARNING_PROPS = /* @__PURE__ */ new Set([
|
|
|
22
22
|
Symbol.toStringTag,
|
|
23
23
|
Symbol.iterator,
|
|
24
24
|
Symbol.toPrimitive
|
|
25
|
-
]
|
|
25
|
+
];
|
|
26
26
|
var SIGNAL_CACHE = /* @__PURE__ */ new WeakMap();
|
|
27
27
|
var BOUND_METHOD_CACHE = /* @__PURE__ */ new WeakMap();
|
|
28
28
|
var ITERATE_KEY = Symbol("iterate");
|
|
@@ -66,18 +66,9 @@ function $store(initialValue) {
|
|
|
66
66
|
const signal = getSignal(target, prop);
|
|
67
67
|
const trackedValue = signal();
|
|
68
68
|
const currentValue = Reflect.get(target, prop, receiver ?? proxy);
|
|
69
|
-
if (isDev && currentValue !== trackedValue && !SKIP_MUTATION_WARNING_PROPS.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
warnedProps = /* @__PURE__ */ new Set();
|
|
73
|
-
MUTATION_WARNED.set(target, warnedProps);
|
|
74
|
-
}
|
|
75
|
-
if (!warnedProps.has(prop)) {
|
|
76
|
-
warnedProps.add(prop);
|
|
77
|
-
console.warn(
|
|
78
|
-
`[fict] Direct mutation detected for "${String(prop)}"; mutate via $store proxy.`
|
|
79
|
-
);
|
|
80
|
-
}
|
|
69
|
+
if (isDev && currentValue !== trackedValue && !SKIP_MUTATION_WARNING_PROPS.includes(prop) && !MUTATION_WARNED.has(target)) {
|
|
70
|
+
MUTATION_WARNED.add(target);
|
|
71
|
+
console.warn(`[fict] Use $store for ${String(prop)}.`);
|
|
81
72
|
}
|
|
82
73
|
if (typeof currentValue === "function") {
|
|
83
74
|
let boundMethods = BOUND_METHOD_CACHE.get(target);
|
|
@@ -130,20 +121,18 @@ function $store(initialValue) {
|
|
|
130
121
|
triggerIteration(target);
|
|
131
122
|
}
|
|
132
123
|
if (Array.isArray(target) && prop !== "length") {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
signals2.length(target.length);
|
|
124
|
+
if (signals && signals.length) {
|
|
125
|
+
signals.length(target.length);
|
|
136
126
|
}
|
|
137
127
|
}
|
|
138
128
|
if (Array.isArray(target) && prop === "length") {
|
|
139
129
|
const nextLength = target.length;
|
|
140
130
|
if (typeof oldLength === "number" && nextLength < oldLength) {
|
|
141
|
-
|
|
142
|
-
if (signals2) {
|
|
131
|
+
if (signals) {
|
|
143
132
|
for (let i = nextLength; i < oldLength; i += 1) {
|
|
144
133
|
const key = String(i);
|
|
145
|
-
if (
|
|
146
|
-
|
|
134
|
+
if (signals[key]) {
|
|
135
|
+
signals[key](void 0);
|
|
147
136
|
}
|
|
148
137
|
}
|
|
149
138
|
}
|
|
@@ -196,7 +185,7 @@ function resource(optionsOrFetcher) {
|
|
|
196
185
|
const cacheOptions = typeof optionsOrFetcher === "object" ? optionsOrFetcher.cache ?? {} : {};
|
|
197
186
|
const resolvedCacheOptions = { ...defaultCacheOptions, ...cacheOptions };
|
|
198
187
|
const cache = /* @__PURE__ */ new Map();
|
|
199
|
-
const readArgs = (argsAccessor) =>
|
|
188
|
+
const readArgs = (argsAccessor) => advanced.isReactive(argsAccessor) ? argsAccessor() : argsAccessor;
|
|
200
189
|
const computeKey = (argsAccessor) => {
|
|
201
190
|
const argsValue = readArgs(argsAccessor);
|
|
202
191
|
if (typeof optionsOrFetcher === "object" && optionsOrFetcher.key !== void 0) {
|
|
@@ -208,7 +197,7 @@ function resource(optionsOrFetcher) {
|
|
|
208
197
|
const readResetToken = () => {
|
|
209
198
|
if (typeof optionsOrFetcher !== "object") return void 0;
|
|
210
199
|
const reset = optionsOrFetcher.reset;
|
|
211
|
-
if (
|
|
200
|
+
if (advanced.isReactive(reset)) {
|
|
212
201
|
return reset();
|
|
213
202
|
}
|
|
214
203
|
return reset;
|