@zag-js/store 0.69.0 → 0.71.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/index.js +13 -47
- package/dist/index.mjs +5 -14
- package/package.json +3 -4
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/src/global.ts +0 -13
- package/src/index.ts +0 -3
- package/src/proxy-computed.ts +0 -33
- package/src/proxy.ts +0 -356
package/dist/index.js
CHANGED
|
@@ -1,33 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
'use strict';
|
|
19
2
|
|
|
20
|
-
|
|
21
|
-
var src_exports = {};
|
|
22
|
-
__export(src_exports, {
|
|
23
|
-
makeGlobal: () => makeGlobal,
|
|
24
|
-
proxy: () => proxy,
|
|
25
|
-
proxyWithComputed: () => proxyWithComputed,
|
|
26
|
-
ref: () => ref,
|
|
27
|
-
snapshot: () => snapshot,
|
|
28
|
-
subscribe: () => subscribe
|
|
29
|
-
});
|
|
30
|
-
module.exports = __toCommonJS(src_exports);
|
|
3
|
+
var proxyCompare = require('proxy-compare');
|
|
31
4
|
|
|
32
5
|
// src/global.ts
|
|
33
6
|
function getGlobal() {
|
|
@@ -42,9 +15,6 @@ function makeGlobal(key, value) {
|
|
|
42
15
|
g[key] || (g[key] = value());
|
|
43
16
|
return g[key];
|
|
44
17
|
}
|
|
45
|
-
|
|
46
|
-
// src/proxy.ts
|
|
47
|
-
var import_proxy_compare = require("proxy-compare");
|
|
48
18
|
var isDev = () => process.env.NODE_ENV !== "production";
|
|
49
19
|
var isObject = (x) => typeof x === "object" && x !== null;
|
|
50
20
|
var proxyStateMap = makeGlobal("__zag__proxyStateMap", () => /* @__PURE__ */ new WeakMap());
|
|
@@ -68,12 +38,12 @@ var buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) =>
|
|
|
68
38
|
return cache[1];
|
|
69
39
|
}
|
|
70
40
|
const snap = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target));
|
|
71
|
-
|
|
41
|
+
proxyCompare.markToTrack(snap, true);
|
|
72
42
|
snapCache.set(target, [version, snap]);
|
|
73
43
|
Reflect.ownKeys(target).forEach((key) => {
|
|
74
44
|
const value = Reflect.get(target, key);
|
|
75
45
|
if (refSet.has(value)) {
|
|
76
|
-
|
|
46
|
+
proxyCompare.markToTrack(value, false);
|
|
77
47
|
snap[key] = value;
|
|
78
48
|
} else if (value instanceof Promise) {
|
|
79
49
|
Object.defineProperty(snap, key, {
|
|
@@ -184,11 +154,10 @@ var buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) =>
|
|
|
184
154
|
}
|
|
185
155
|
removePropListener(prop);
|
|
186
156
|
if (isObject(value)) {
|
|
187
|
-
value =
|
|
157
|
+
value = proxyCompare.getUntracked(value) || value;
|
|
188
158
|
}
|
|
189
159
|
let nextValue = value;
|
|
190
|
-
if (Object.getOwnPropertyDescriptor(target, prop)?.set) {
|
|
191
|
-
} else if (value instanceof Promise) {
|
|
160
|
+
if (Object.getOwnPropertyDescriptor(target, prop)?.set) ; else if (value instanceof Promise) {
|
|
192
161
|
value.then((v) => {
|
|
193
162
|
Object.assign(value, { status: "fulfilled", value: v });
|
|
194
163
|
notifyUpdate(["resolve", [prop], v]);
|
|
@@ -306,13 +275,10 @@ function proxyWithComputed(initialObject, computedFns) {
|
|
|
306
275
|
const proxyObject = proxy(initialObject);
|
|
307
276
|
return proxyObject;
|
|
308
277
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
subscribe
|
|
317
|
-
});
|
|
318
|
-
//# sourceMappingURL=index.js.map
|
|
278
|
+
|
|
279
|
+
exports.makeGlobal = makeGlobal;
|
|
280
|
+
exports.proxy = proxy;
|
|
281
|
+
exports.proxyWithComputed = proxyWithComputed;
|
|
282
|
+
exports.ref = ref;
|
|
283
|
+
exports.snapshot = snapshot;
|
|
284
|
+
exports.subscribe = subscribe;
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { markToTrack, getUntracked } from 'proxy-compare';
|
|
2
|
+
|
|
1
3
|
// src/global.ts
|
|
2
4
|
function getGlobal() {
|
|
3
5
|
if (typeof globalThis !== "undefined") return globalThis;
|
|
@@ -11,9 +13,6 @@ function makeGlobal(key, value) {
|
|
|
11
13
|
g[key] || (g[key] = value());
|
|
12
14
|
return g[key];
|
|
13
15
|
}
|
|
14
|
-
|
|
15
|
-
// src/proxy.ts
|
|
16
|
-
import { getUntracked, markToTrack } from "proxy-compare";
|
|
17
16
|
var isDev = () => process.env.NODE_ENV !== "production";
|
|
18
17
|
var isObject = (x) => typeof x === "object" && x !== null;
|
|
19
18
|
var proxyStateMap = makeGlobal("__zag__proxyStateMap", () => /* @__PURE__ */ new WeakMap());
|
|
@@ -156,8 +155,7 @@ var buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) =>
|
|
|
156
155
|
value = getUntracked(value) || value;
|
|
157
156
|
}
|
|
158
157
|
let nextValue = value;
|
|
159
|
-
if (Object.getOwnPropertyDescriptor(target, prop)?.set) {
|
|
160
|
-
} else if (value instanceof Promise) {
|
|
158
|
+
if (Object.getOwnPropertyDescriptor(target, prop)?.set) ; else if (value instanceof Promise) {
|
|
161
159
|
value.then((v) => {
|
|
162
160
|
Object.assign(value, { status: "fulfilled", value: v });
|
|
163
161
|
notifyUpdate(["resolve", [prop], v]);
|
|
@@ -275,12 +273,5 @@ function proxyWithComputed(initialObject, computedFns) {
|
|
|
275
273
|
const proxyObject = proxy(initialObject);
|
|
276
274
|
return proxyObject;
|
|
277
275
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
proxy,
|
|
281
|
-
proxyWithComputed,
|
|
282
|
-
ref,
|
|
283
|
-
snapshot,
|
|
284
|
-
subscribe
|
|
285
|
-
};
|
|
286
|
-
//# sourceMappingURL=index.mjs.map
|
|
276
|
+
|
|
277
|
+
export { makeGlobal, proxy, proxyWithComputed, ref, snapshot, subscribe };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/store",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.71.0",
|
|
4
4
|
"description": "The reactive store package for zag machines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
"repository": "https://github.com/chakra-ui/zag/tree/main/packages/utilities/store",
|
|
15
15
|
"sideEffects": false,
|
|
16
16
|
"files": [
|
|
17
|
-
"dist"
|
|
18
|
-
"src"
|
|
17
|
+
"dist"
|
|
19
18
|
],
|
|
20
19
|
"publishConfig": {
|
|
21
20
|
"access": "public"
|
|
@@ -43,7 +42,7 @@
|
|
|
43
42
|
},
|
|
44
43
|
"scripts": {
|
|
45
44
|
"build": "tsup",
|
|
46
|
-
"test": "
|
|
45
|
+
"test": "vitest",
|
|
47
46
|
"lint": "eslint src",
|
|
48
47
|
"test-ci": "pnpm test --ci --runInBand -u",
|
|
49
48
|
"test-watch": "pnpm test --watchAll"
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/global.ts","../src/proxy.ts","../src/proxy-computed.ts"],"sourcesContent":["export { makeGlobal } from \"./global\"\nexport { proxy, ref, snapshot, subscribe, type Ref, type Snapshot } from \"./proxy\"\nexport { proxyWithComputed } from \"./proxy-computed\"\n","function getGlobal(): any {\n if (typeof globalThis !== \"undefined\") return globalThis\n if (typeof self !== \"undefined\") return self\n if (typeof window !== \"undefined\") return window\n if (typeof global !== \"undefined\") return global\n}\n\nexport function makeGlobal<T>(key: string, value: () => T): T {\n const g = getGlobal()\n if (!g) return value()\n g[key] ||= value()\n return g[key]\n}\n","// Credits: https://github.com/pmndrs/valtio\n\nimport { getUntracked, markToTrack } from \"proxy-compare\"\nimport { makeGlobal } from \"./global\"\n\nconst isDev = () => process.env.NODE_ENV !== \"production\"\nconst isObject = (x: unknown): x is object => typeof x === \"object\" && x !== null\n\ntype AsRef = { $$valtioRef: true }\n\ntype ProxyObject = object\n\ntype Path = (string | symbol)[]\n\ntype Op =\n | [op: \"set\", path: Path, value: unknown, prevValue: unknown]\n | [op: \"delete\", path: Path, prevValue: unknown]\n | [op: \"resolve\", path: Path, value: unknown]\n | [op: \"reject\", path: Path, error: unknown]\n\ntype Listener = (op: Op, nextVersion: number) => void\n\ntype AnyFunction = (...args: any[]) => any\n\nexport type Snapshot<T> = T extends AnyFunction\n ? T\n : T extends AsRef\n ? T\n : T extends Promise<any>\n ? Awaited<T>\n : {\n readonly [K in keyof T]: Snapshot<T[K]>\n }\n\ntype HandlePromise = <P extends Promise<any>>(promise: P) => Awaited<P>\n\ntype CreateSnapshot = <T extends object>(target: T, version: number, handlePromise?: HandlePromise) => T\n\ntype RemoveListener = () => void\ntype AddListener = (listener: Listener) => RemoveListener\n\ntype ProxyState = readonly [\n target: object,\n ensureVersion: (nextCheckVersion?: number) => number,\n createSnapshot: CreateSnapshot,\n addListener: AddListener,\n]\n\n// shared state\nconst proxyStateMap = makeGlobal(\"__zag__proxyStateMap\", () => new WeakMap<ProxyObject, ProxyState>())\nconst refSet = makeGlobal(\"__zag__refSet\", () => new WeakSet())\n\nconst isReactElement = (x: any) => typeof x === \"object\" && x !== null && \"$$typeof\" in x\nconst isVueElement = (x: any) => typeof x === \"object\" && x !== null && \"__v_isVNode\" in x\nconst isDOMElement = (x: any) =>\n typeof x === \"object\" && x !== null && \"nodeType\" in x && typeof x.nodeName === \"string\"\nconst isElement = (x: any) => isReactElement(x) || isVueElement(x) || isDOMElement(x)\n\nconst buildProxyFunction = (\n objectIs = Object.is,\n\n newProxy = <T extends object>(target: T, handler: ProxyHandler<T>): T => new Proxy(target, handler),\n\n canProxy = (x: unknown) =>\n isObject(x) &&\n !refSet.has(x) &&\n (Array.isArray(x) || !(Symbol.iterator in x)) &&\n !isElement(x) &&\n !(x instanceof WeakMap) &&\n !(x instanceof WeakSet) &&\n !(x instanceof Error) &&\n !(x instanceof Number) &&\n !(x instanceof Date) &&\n !(x instanceof String) &&\n !(x instanceof RegExp) &&\n !(x instanceof ArrayBuffer),\n\n defaultHandlePromise = <P extends Promise<any>>(\n promise: P & {\n status?: \"pending\" | \"fulfilled\" | \"rejected\"\n value?: Awaited<P>\n reason?: unknown\n },\n ) => {\n switch (promise.status) {\n case \"fulfilled\":\n return promise.value as Awaited<P>\n case \"rejected\":\n throw promise.reason\n default:\n throw promise\n }\n },\n\n snapCache = new WeakMap<object, [version: number, snap: unknown]>(),\n\n createSnapshot: CreateSnapshot = <T extends object>(\n target: T,\n version: number,\n handlePromise: HandlePromise = defaultHandlePromise,\n ): T => {\n const cache = snapCache.get(target)\n if (cache?.[0] === version) {\n return cache[1] as T\n }\n const snap: any = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target))\n markToTrack(snap, true) // mark to track\n snapCache.set(target, [version, snap])\n Reflect.ownKeys(target).forEach((key) => {\n const value = Reflect.get(target, key)\n if (refSet.has(value as object)) {\n markToTrack(value as object, false) // mark not to track\n snap[key] = value\n } else if (value instanceof Promise) {\n Object.defineProperty(snap, key, {\n get() {\n return handlePromise(value)\n },\n })\n } else if (proxyStateMap.has(value as object)) {\n snap[key] = snapshot(value as object, handlePromise)\n } else {\n snap[key] = value\n }\n })\n return Object.freeze(snap)\n },\n\n proxyCache = new WeakMap<object, ProxyObject>(),\n\n versionHolder = [1, 1] as [number, number],\n\n proxyFunction = <T extends object>(initialObject: T): T => {\n if (!isObject(initialObject)) {\n throw new Error(\"object required\")\n }\n const found = proxyCache.get(initialObject) as T | undefined\n if (found) {\n return found\n }\n let version = versionHolder[0]\n const listeners = new Set<Listener>()\n const notifyUpdate = (op: Op, nextVersion = ++versionHolder[0]) => {\n if (version !== nextVersion) {\n version = nextVersion\n listeners.forEach((listener) => listener(op, nextVersion))\n }\n }\n let checkVersion = versionHolder[1]\n const ensureVersion = (nextCheckVersion = ++versionHolder[1]) => {\n if (checkVersion !== nextCheckVersion && !listeners.size) {\n checkVersion = nextCheckVersion\n propProxyStates.forEach(([propProxyState]) => {\n const propVersion = propProxyState[1](nextCheckVersion)\n if (propVersion > version) {\n version = propVersion\n }\n })\n }\n return version\n }\n const createPropListener =\n (prop: string | symbol): Listener =>\n (op, nextVersion) => {\n const newOp: Op = [...op]\n newOp[1] = [prop, ...(newOp[1] as Path)]\n notifyUpdate(newOp, nextVersion)\n }\n const propProxyStates = new Map<string | symbol, readonly [ProxyState, RemoveListener?]>()\n const addPropListener = (prop: string | symbol, propProxyState: ProxyState) => {\n if (isDev() && propProxyStates.has(prop)) {\n throw new Error(\"prop listener already exists\")\n }\n if (listeners.size) {\n const remove = propProxyState[3](createPropListener(prop))\n propProxyStates.set(prop, [propProxyState, remove])\n } else {\n propProxyStates.set(prop, [propProxyState])\n }\n }\n const removePropListener = (prop: string | symbol) => {\n const entry = propProxyStates.get(prop)\n if (entry) {\n propProxyStates.delete(prop)\n entry[1]?.()\n }\n }\n const addListener = (listener: Listener) => {\n listeners.add(listener)\n if (listeners.size === 1) {\n propProxyStates.forEach(([propProxyState, prevRemove], prop) => {\n if (isDev() && prevRemove) {\n throw new Error(\"remove already exists\")\n }\n const remove = propProxyState[3](createPropListener(prop))\n propProxyStates.set(prop, [propProxyState, remove])\n })\n }\n const removeListener = () => {\n listeners.delete(listener)\n if (listeners.size === 0) {\n propProxyStates.forEach(([propProxyState, remove], prop) => {\n if (remove) {\n remove()\n propProxyStates.set(prop, [propProxyState])\n }\n })\n }\n }\n return removeListener\n }\n const baseObject = Array.isArray(initialObject) ? [] : Object.create(Object.getPrototypeOf(initialObject))\n const handler: ProxyHandler<T> = {\n deleteProperty(target: T, prop: string | symbol) {\n const prevValue = Reflect.get(target, prop)\n removePropListener(prop)\n const deleted = Reflect.deleteProperty(target, prop)\n if (deleted) {\n notifyUpdate([\"delete\", [prop], prevValue])\n }\n return deleted\n },\n set(target: T, prop: string | symbol, value: any, receiver: object) {\n const hasPrevValue = Reflect.has(target, prop)\n const prevValue = Reflect.get(target, prop, receiver)\n if (\n hasPrevValue &&\n (objectIs(prevValue, value) || (proxyCache.has(value) && objectIs(prevValue, proxyCache.get(value))))\n ) {\n return true\n }\n removePropListener(prop)\n if (isObject(value)) {\n value = getUntracked(value) || value\n }\n let nextValue = value\n if (Object.getOwnPropertyDescriptor(target, prop)?.set) {\n // do nothing\n } else if (value instanceof Promise) {\n value\n .then((v) => {\n Object.assign(value, { status: \"fulfilled\", value: v })\n notifyUpdate([\"resolve\", [prop], v])\n })\n .catch((e) => {\n Object.assign(value, { status: \"rejected\", reason: e })\n notifyUpdate([\"reject\", [prop], e])\n })\n } else {\n if (!proxyStateMap.has(value) && canProxy(value)) {\n nextValue = proxy(value)\n }\n const childProxyState = !refSet.has(nextValue) && proxyStateMap.get(nextValue)\n if (childProxyState) {\n addPropListener(prop, childProxyState)\n }\n }\n Reflect.set(target, prop, nextValue, receiver)\n notifyUpdate([\"set\", [prop], value, prevValue])\n return true\n },\n }\n const proxyObject = newProxy(baseObject, handler)\n proxyCache.set(initialObject, proxyObject)\n const proxyState: ProxyState = [baseObject, ensureVersion, createSnapshot, addListener]\n proxyStateMap.set(proxyObject, proxyState)\n Reflect.ownKeys(initialObject).forEach((key) => {\n const desc = Object.getOwnPropertyDescriptor(initialObject, key) as PropertyDescriptor\n if (desc.get || desc.set) {\n Object.defineProperty(baseObject, key, desc)\n } else {\n proxyObject[key as keyof T] = initialObject[key as keyof T]\n }\n })\n return proxyObject\n },\n) =>\n [\n // public functions\n proxyFunction,\n // shared state\n proxyStateMap,\n refSet,\n // internal things\n objectIs,\n newProxy,\n canProxy,\n defaultHandlePromise,\n snapCache,\n createSnapshot,\n proxyCache,\n versionHolder,\n ] as const\n\nconst [proxyFunction] = buildProxyFunction()\n\nexport function proxy<T extends object>(initialObject: T = {} as T): T {\n return proxyFunction(initialObject)\n}\n\nexport function getVersion(proxyObject: unknown): number | undefined {\n const proxyState = proxyStateMap.get(proxyObject as object)\n return proxyState?.[1]()\n}\n\nexport function subscribe<T extends object>(\n proxyObject: T,\n callback: (ops: Op[]) => void,\n notifyInSync?: boolean,\n): () => void {\n const proxyState = proxyStateMap.get(proxyObject as object)\n if (isDev() && !proxyState) {\n console.warn(\"Please use proxy object\")\n }\n let promise: Promise<void> | undefined\n const ops: Op[] = []\n const addListener = (proxyState as ProxyState)[3]\n let isListenerActive = false\n const listener: Listener = (op) => {\n ops.push(op)\n if (notifyInSync) {\n callback(ops.splice(0))\n return\n }\n if (!promise) {\n promise = Promise.resolve().then(() => {\n promise = undefined\n if (isListenerActive) {\n callback(ops.splice(0))\n }\n })\n }\n }\n const removeListener = addListener(listener)\n isListenerActive = true\n return () => {\n isListenerActive = false\n removeListener()\n }\n}\n\nexport function snapshot<T extends object>(proxyObject: T, handlePromise?: HandlePromise): Snapshot<T> {\n const proxyState = proxyStateMap.get(proxyObject as object)\n if (isDev() && !proxyState) {\n console.warn(\"Please use proxy object\")\n }\n const [target, ensureVersion, createSnapshot] = proxyState as ProxyState\n return createSnapshot(target, ensureVersion(), handlePromise) as Snapshot<T>\n}\n\nexport function ref<T extends object>(obj: T): Ref<T> {\n refSet.add(obj)\n return obj as T & AsRef\n}\n\nexport type Ref<T> = T & AsRef\n","import { proxy, snapshot, type Snapshot } from \"./proxy\"\n\nexport function proxyWithComputed<T extends object, U extends object>(\n initialObject: T,\n computedFns: {\n [K in keyof U]:\n | ((snap: Snapshot<T>) => U[K])\n | {\n get: (snap: Snapshot<T>) => U[K]\n set?: (state: T, newValue: U[K]) => void\n }\n },\n) {\n const keys = Object.keys(computedFns) as (keyof U)[]\n keys.forEach((key) => {\n if (Object.getOwnPropertyDescriptor(initialObject, key)) {\n throw new Error(\"object property already defined\")\n }\n const computedFn = computedFns[key]\n const { get, set } = (typeof computedFn === \"function\" ? { get: computedFn } : computedFn) as {\n get: (snap: Snapshot<T>) => U[typeof key]\n set?: (state: T, newValue: U[typeof key]) => void\n }\n const desc: PropertyDescriptor = {}\n desc.get = () => get(snapshot(proxyObject))\n if (set) {\n desc.set = (newValue) => set(proxyObject, newValue)\n }\n Object.defineProperty(initialObject, key, desc)\n })\n const proxyObject = proxy(initialObject) as T & U\n return proxyObject\n}\n"],"mappings":"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","names":["proxyFunction"]}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/global.ts","../src/proxy.ts","../src/proxy-computed.ts"],"sourcesContent":["function getGlobal(): any {\n if (typeof globalThis !== \"undefined\") return globalThis\n if (typeof self !== \"undefined\") return self\n if (typeof window !== \"undefined\") return window\n if (typeof global !== \"undefined\") return global\n}\n\nexport function makeGlobal<T>(key: string, value: () => T): T {\n const g = getGlobal()\n if (!g) return value()\n g[key] ||= value()\n return g[key]\n}\n","// Credits: https://github.com/pmndrs/valtio\n\nimport { getUntracked, markToTrack } from \"proxy-compare\"\nimport { makeGlobal } from \"./global\"\n\nconst isDev = () => process.env.NODE_ENV !== \"production\"\nconst isObject = (x: unknown): x is object => typeof x === \"object\" && x !== null\n\ntype AsRef = { $$valtioRef: true }\n\ntype ProxyObject = object\n\ntype Path = (string | symbol)[]\n\ntype Op =\n | [op: \"set\", path: Path, value: unknown, prevValue: unknown]\n | [op: \"delete\", path: Path, prevValue: unknown]\n | [op: \"resolve\", path: Path, value: unknown]\n | [op: \"reject\", path: Path, error: unknown]\n\ntype Listener = (op: Op, nextVersion: number) => void\n\ntype AnyFunction = (...args: any[]) => any\n\nexport type Snapshot<T> = T extends AnyFunction\n ? T\n : T extends AsRef\n ? T\n : T extends Promise<any>\n ? Awaited<T>\n : {\n readonly [K in keyof T]: Snapshot<T[K]>\n }\n\ntype HandlePromise = <P extends Promise<any>>(promise: P) => Awaited<P>\n\ntype CreateSnapshot = <T extends object>(target: T, version: number, handlePromise?: HandlePromise) => T\n\ntype RemoveListener = () => void\ntype AddListener = (listener: Listener) => RemoveListener\n\ntype ProxyState = readonly [\n target: object,\n ensureVersion: (nextCheckVersion?: number) => number,\n createSnapshot: CreateSnapshot,\n addListener: AddListener,\n]\n\n// shared state\nconst proxyStateMap = makeGlobal(\"__zag__proxyStateMap\", () => new WeakMap<ProxyObject, ProxyState>())\nconst refSet = makeGlobal(\"__zag__refSet\", () => new WeakSet())\n\nconst isReactElement = (x: any) => typeof x === \"object\" && x !== null && \"$$typeof\" in x\nconst isVueElement = (x: any) => typeof x === \"object\" && x !== null && \"__v_isVNode\" in x\nconst isDOMElement = (x: any) =>\n typeof x === \"object\" && x !== null && \"nodeType\" in x && typeof x.nodeName === \"string\"\nconst isElement = (x: any) => isReactElement(x) || isVueElement(x) || isDOMElement(x)\n\nconst buildProxyFunction = (\n objectIs = Object.is,\n\n newProxy = <T extends object>(target: T, handler: ProxyHandler<T>): T => new Proxy(target, handler),\n\n canProxy = (x: unknown) =>\n isObject(x) &&\n !refSet.has(x) &&\n (Array.isArray(x) || !(Symbol.iterator in x)) &&\n !isElement(x) &&\n !(x instanceof WeakMap) &&\n !(x instanceof WeakSet) &&\n !(x instanceof Error) &&\n !(x instanceof Number) &&\n !(x instanceof Date) &&\n !(x instanceof String) &&\n !(x instanceof RegExp) &&\n !(x instanceof ArrayBuffer),\n\n defaultHandlePromise = <P extends Promise<any>>(\n promise: P & {\n status?: \"pending\" | \"fulfilled\" | \"rejected\"\n value?: Awaited<P>\n reason?: unknown\n },\n ) => {\n switch (promise.status) {\n case \"fulfilled\":\n return promise.value as Awaited<P>\n case \"rejected\":\n throw promise.reason\n default:\n throw promise\n }\n },\n\n snapCache = new WeakMap<object, [version: number, snap: unknown]>(),\n\n createSnapshot: CreateSnapshot = <T extends object>(\n target: T,\n version: number,\n handlePromise: HandlePromise = defaultHandlePromise,\n ): T => {\n const cache = snapCache.get(target)\n if (cache?.[0] === version) {\n return cache[1] as T\n }\n const snap: any = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target))\n markToTrack(snap, true) // mark to track\n snapCache.set(target, [version, snap])\n Reflect.ownKeys(target).forEach((key) => {\n const value = Reflect.get(target, key)\n if (refSet.has(value as object)) {\n markToTrack(value as object, false) // mark not to track\n snap[key] = value\n } else if (value instanceof Promise) {\n Object.defineProperty(snap, key, {\n get() {\n return handlePromise(value)\n },\n })\n } else if (proxyStateMap.has(value as object)) {\n snap[key] = snapshot(value as object, handlePromise)\n } else {\n snap[key] = value\n }\n })\n return Object.freeze(snap)\n },\n\n proxyCache = new WeakMap<object, ProxyObject>(),\n\n versionHolder = [1, 1] as [number, number],\n\n proxyFunction = <T extends object>(initialObject: T): T => {\n if (!isObject(initialObject)) {\n throw new Error(\"object required\")\n }\n const found = proxyCache.get(initialObject) as T | undefined\n if (found) {\n return found\n }\n let version = versionHolder[0]\n const listeners = new Set<Listener>()\n const notifyUpdate = (op: Op, nextVersion = ++versionHolder[0]) => {\n if (version !== nextVersion) {\n version = nextVersion\n listeners.forEach((listener) => listener(op, nextVersion))\n }\n }\n let checkVersion = versionHolder[1]\n const ensureVersion = (nextCheckVersion = ++versionHolder[1]) => {\n if (checkVersion !== nextCheckVersion && !listeners.size) {\n checkVersion = nextCheckVersion\n propProxyStates.forEach(([propProxyState]) => {\n const propVersion = propProxyState[1](nextCheckVersion)\n if (propVersion > version) {\n version = propVersion\n }\n })\n }\n return version\n }\n const createPropListener =\n (prop: string | symbol): Listener =>\n (op, nextVersion) => {\n const newOp: Op = [...op]\n newOp[1] = [prop, ...(newOp[1] as Path)]\n notifyUpdate(newOp, nextVersion)\n }\n const propProxyStates = new Map<string | symbol, readonly [ProxyState, RemoveListener?]>()\n const addPropListener = (prop: string | symbol, propProxyState: ProxyState) => {\n if (isDev() && propProxyStates.has(prop)) {\n throw new Error(\"prop listener already exists\")\n }\n if (listeners.size) {\n const remove = propProxyState[3](createPropListener(prop))\n propProxyStates.set(prop, [propProxyState, remove])\n } else {\n propProxyStates.set(prop, [propProxyState])\n }\n }\n const removePropListener = (prop: string | symbol) => {\n const entry = propProxyStates.get(prop)\n if (entry) {\n propProxyStates.delete(prop)\n entry[1]?.()\n }\n }\n const addListener = (listener: Listener) => {\n listeners.add(listener)\n if (listeners.size === 1) {\n propProxyStates.forEach(([propProxyState, prevRemove], prop) => {\n if (isDev() && prevRemove) {\n throw new Error(\"remove already exists\")\n }\n const remove = propProxyState[3](createPropListener(prop))\n propProxyStates.set(prop, [propProxyState, remove])\n })\n }\n const removeListener = () => {\n listeners.delete(listener)\n if (listeners.size === 0) {\n propProxyStates.forEach(([propProxyState, remove], prop) => {\n if (remove) {\n remove()\n propProxyStates.set(prop, [propProxyState])\n }\n })\n }\n }\n return removeListener\n }\n const baseObject = Array.isArray(initialObject) ? [] : Object.create(Object.getPrototypeOf(initialObject))\n const handler: ProxyHandler<T> = {\n deleteProperty(target: T, prop: string | symbol) {\n const prevValue = Reflect.get(target, prop)\n removePropListener(prop)\n const deleted = Reflect.deleteProperty(target, prop)\n if (deleted) {\n notifyUpdate([\"delete\", [prop], prevValue])\n }\n return deleted\n },\n set(target: T, prop: string | symbol, value: any, receiver: object) {\n const hasPrevValue = Reflect.has(target, prop)\n const prevValue = Reflect.get(target, prop, receiver)\n if (\n hasPrevValue &&\n (objectIs(prevValue, value) || (proxyCache.has(value) && objectIs(prevValue, proxyCache.get(value))))\n ) {\n return true\n }\n removePropListener(prop)\n if (isObject(value)) {\n value = getUntracked(value) || value\n }\n let nextValue = value\n if (Object.getOwnPropertyDescriptor(target, prop)?.set) {\n // do nothing\n } else if (value instanceof Promise) {\n value\n .then((v) => {\n Object.assign(value, { status: \"fulfilled\", value: v })\n notifyUpdate([\"resolve\", [prop], v])\n })\n .catch((e) => {\n Object.assign(value, { status: \"rejected\", reason: e })\n notifyUpdate([\"reject\", [prop], e])\n })\n } else {\n if (!proxyStateMap.has(value) && canProxy(value)) {\n nextValue = proxy(value)\n }\n const childProxyState = !refSet.has(nextValue) && proxyStateMap.get(nextValue)\n if (childProxyState) {\n addPropListener(prop, childProxyState)\n }\n }\n Reflect.set(target, prop, nextValue, receiver)\n notifyUpdate([\"set\", [prop], value, prevValue])\n return true\n },\n }\n const proxyObject = newProxy(baseObject, handler)\n proxyCache.set(initialObject, proxyObject)\n const proxyState: ProxyState = [baseObject, ensureVersion, createSnapshot, addListener]\n proxyStateMap.set(proxyObject, proxyState)\n Reflect.ownKeys(initialObject).forEach((key) => {\n const desc = Object.getOwnPropertyDescriptor(initialObject, key) as PropertyDescriptor\n if (desc.get || desc.set) {\n Object.defineProperty(baseObject, key, desc)\n } else {\n proxyObject[key as keyof T] = initialObject[key as keyof T]\n }\n })\n return proxyObject\n },\n) =>\n [\n // public functions\n proxyFunction,\n // shared state\n proxyStateMap,\n refSet,\n // internal things\n objectIs,\n newProxy,\n canProxy,\n defaultHandlePromise,\n snapCache,\n createSnapshot,\n proxyCache,\n versionHolder,\n ] as const\n\nconst [proxyFunction] = buildProxyFunction()\n\nexport function proxy<T extends object>(initialObject: T = {} as T): T {\n return proxyFunction(initialObject)\n}\n\nexport function getVersion(proxyObject: unknown): number | undefined {\n const proxyState = proxyStateMap.get(proxyObject as object)\n return proxyState?.[1]()\n}\n\nexport function subscribe<T extends object>(\n proxyObject: T,\n callback: (ops: Op[]) => void,\n notifyInSync?: boolean,\n): () => void {\n const proxyState = proxyStateMap.get(proxyObject as object)\n if (isDev() && !proxyState) {\n console.warn(\"Please use proxy object\")\n }\n let promise: Promise<void> | undefined\n const ops: Op[] = []\n const addListener = (proxyState as ProxyState)[3]\n let isListenerActive = false\n const listener: Listener = (op) => {\n ops.push(op)\n if (notifyInSync) {\n callback(ops.splice(0))\n return\n }\n if (!promise) {\n promise = Promise.resolve().then(() => {\n promise = undefined\n if (isListenerActive) {\n callback(ops.splice(0))\n }\n })\n }\n }\n const removeListener = addListener(listener)\n isListenerActive = true\n return () => {\n isListenerActive = false\n removeListener()\n }\n}\n\nexport function snapshot<T extends object>(proxyObject: T, handlePromise?: HandlePromise): Snapshot<T> {\n const proxyState = proxyStateMap.get(proxyObject as object)\n if (isDev() && !proxyState) {\n console.warn(\"Please use proxy object\")\n }\n const [target, ensureVersion, createSnapshot] = proxyState as ProxyState\n return createSnapshot(target, ensureVersion(), handlePromise) as Snapshot<T>\n}\n\nexport function ref<T extends object>(obj: T): Ref<T> {\n refSet.add(obj)\n return obj as T & AsRef\n}\n\nexport type Ref<T> = T & AsRef\n","import { proxy, snapshot, type Snapshot } from \"./proxy\"\n\nexport function proxyWithComputed<T extends object, U extends object>(\n initialObject: T,\n computedFns: {\n [K in keyof U]:\n | ((snap: Snapshot<T>) => U[K])\n | {\n get: (snap: Snapshot<T>) => U[K]\n set?: (state: T, newValue: U[K]) => void\n }\n },\n) {\n const keys = Object.keys(computedFns) as (keyof U)[]\n keys.forEach((key) => {\n if (Object.getOwnPropertyDescriptor(initialObject, key)) {\n throw new Error(\"object property already defined\")\n }\n const computedFn = computedFns[key]\n const { get, set } = (typeof computedFn === \"function\" ? { get: computedFn } : computedFn) as {\n get: (snap: Snapshot<T>) => U[typeof key]\n set?: (state: T, newValue: U[typeof key]) => void\n }\n const desc: PropertyDescriptor = {}\n desc.get = () => get(snapshot(proxyObject))\n if (set) {\n desc.set = (newValue) => set(proxyObject, newValue)\n }\n Object.defineProperty(initialObject, key, desc)\n })\n const proxyObject = proxy(initialObject) as T & U\n return proxyObject\n}\n"],"mappings":"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","names":["proxyFunction"]}
|
package/src/global.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
function getGlobal(): any {
|
|
2
|
-
if (typeof globalThis !== "undefined") return globalThis
|
|
3
|
-
if (typeof self !== "undefined") return self
|
|
4
|
-
if (typeof window !== "undefined") return window
|
|
5
|
-
if (typeof global !== "undefined") return global
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function makeGlobal<T>(key: string, value: () => T): T {
|
|
9
|
-
const g = getGlobal()
|
|
10
|
-
if (!g) return value()
|
|
11
|
-
g[key] ||= value()
|
|
12
|
-
return g[key]
|
|
13
|
-
}
|
package/src/index.ts
DELETED
package/src/proxy-computed.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { proxy, snapshot, type Snapshot } from "./proxy"
|
|
2
|
-
|
|
3
|
-
export function proxyWithComputed<T extends object, U extends object>(
|
|
4
|
-
initialObject: T,
|
|
5
|
-
computedFns: {
|
|
6
|
-
[K in keyof U]:
|
|
7
|
-
| ((snap: Snapshot<T>) => U[K])
|
|
8
|
-
| {
|
|
9
|
-
get: (snap: Snapshot<T>) => U[K]
|
|
10
|
-
set?: (state: T, newValue: U[K]) => void
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
) {
|
|
14
|
-
const keys = Object.keys(computedFns) as (keyof U)[]
|
|
15
|
-
keys.forEach((key) => {
|
|
16
|
-
if (Object.getOwnPropertyDescriptor(initialObject, key)) {
|
|
17
|
-
throw new Error("object property already defined")
|
|
18
|
-
}
|
|
19
|
-
const computedFn = computedFns[key]
|
|
20
|
-
const { get, set } = (typeof computedFn === "function" ? { get: computedFn } : computedFn) as {
|
|
21
|
-
get: (snap: Snapshot<T>) => U[typeof key]
|
|
22
|
-
set?: (state: T, newValue: U[typeof key]) => void
|
|
23
|
-
}
|
|
24
|
-
const desc: PropertyDescriptor = {}
|
|
25
|
-
desc.get = () => get(snapshot(proxyObject))
|
|
26
|
-
if (set) {
|
|
27
|
-
desc.set = (newValue) => set(proxyObject, newValue)
|
|
28
|
-
}
|
|
29
|
-
Object.defineProperty(initialObject, key, desc)
|
|
30
|
-
})
|
|
31
|
-
const proxyObject = proxy(initialObject) as T & U
|
|
32
|
-
return proxyObject
|
|
33
|
-
}
|
package/src/proxy.ts
DELETED
|
@@ -1,356 +0,0 @@
|
|
|
1
|
-
// Credits: https://github.com/pmndrs/valtio
|
|
2
|
-
|
|
3
|
-
import { getUntracked, markToTrack } from "proxy-compare"
|
|
4
|
-
import { makeGlobal } from "./global"
|
|
5
|
-
|
|
6
|
-
const isDev = () => process.env.NODE_ENV !== "production"
|
|
7
|
-
const isObject = (x: unknown): x is object => typeof x === "object" && x !== null
|
|
8
|
-
|
|
9
|
-
type AsRef = { $$valtioRef: true }
|
|
10
|
-
|
|
11
|
-
type ProxyObject = object
|
|
12
|
-
|
|
13
|
-
type Path = (string | symbol)[]
|
|
14
|
-
|
|
15
|
-
type Op =
|
|
16
|
-
| [op: "set", path: Path, value: unknown, prevValue: unknown]
|
|
17
|
-
| [op: "delete", path: Path, prevValue: unknown]
|
|
18
|
-
| [op: "resolve", path: Path, value: unknown]
|
|
19
|
-
| [op: "reject", path: Path, error: unknown]
|
|
20
|
-
|
|
21
|
-
type Listener = (op: Op, nextVersion: number) => void
|
|
22
|
-
|
|
23
|
-
type AnyFunction = (...args: any[]) => any
|
|
24
|
-
|
|
25
|
-
export type Snapshot<T> = T extends AnyFunction
|
|
26
|
-
? T
|
|
27
|
-
: T extends AsRef
|
|
28
|
-
? T
|
|
29
|
-
: T extends Promise<any>
|
|
30
|
-
? Awaited<T>
|
|
31
|
-
: {
|
|
32
|
-
readonly [K in keyof T]: Snapshot<T[K]>
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
type HandlePromise = <P extends Promise<any>>(promise: P) => Awaited<P>
|
|
36
|
-
|
|
37
|
-
type CreateSnapshot = <T extends object>(target: T, version: number, handlePromise?: HandlePromise) => T
|
|
38
|
-
|
|
39
|
-
type RemoveListener = () => void
|
|
40
|
-
type AddListener = (listener: Listener) => RemoveListener
|
|
41
|
-
|
|
42
|
-
type ProxyState = readonly [
|
|
43
|
-
target: object,
|
|
44
|
-
ensureVersion: (nextCheckVersion?: number) => number,
|
|
45
|
-
createSnapshot: CreateSnapshot,
|
|
46
|
-
addListener: AddListener,
|
|
47
|
-
]
|
|
48
|
-
|
|
49
|
-
// shared state
|
|
50
|
-
const proxyStateMap = makeGlobal("__zag__proxyStateMap", () => new WeakMap<ProxyObject, ProxyState>())
|
|
51
|
-
const refSet = makeGlobal("__zag__refSet", () => new WeakSet())
|
|
52
|
-
|
|
53
|
-
const isReactElement = (x: any) => typeof x === "object" && x !== null && "$$typeof" in x
|
|
54
|
-
const isVueElement = (x: any) => typeof x === "object" && x !== null && "__v_isVNode" in x
|
|
55
|
-
const isDOMElement = (x: any) =>
|
|
56
|
-
typeof x === "object" && x !== null && "nodeType" in x && typeof x.nodeName === "string"
|
|
57
|
-
const isElement = (x: any) => isReactElement(x) || isVueElement(x) || isDOMElement(x)
|
|
58
|
-
|
|
59
|
-
const buildProxyFunction = (
|
|
60
|
-
objectIs = Object.is,
|
|
61
|
-
|
|
62
|
-
newProxy = <T extends object>(target: T, handler: ProxyHandler<T>): T => new Proxy(target, handler),
|
|
63
|
-
|
|
64
|
-
canProxy = (x: unknown) =>
|
|
65
|
-
isObject(x) &&
|
|
66
|
-
!refSet.has(x) &&
|
|
67
|
-
(Array.isArray(x) || !(Symbol.iterator in x)) &&
|
|
68
|
-
!isElement(x) &&
|
|
69
|
-
!(x instanceof WeakMap) &&
|
|
70
|
-
!(x instanceof WeakSet) &&
|
|
71
|
-
!(x instanceof Error) &&
|
|
72
|
-
!(x instanceof Number) &&
|
|
73
|
-
!(x instanceof Date) &&
|
|
74
|
-
!(x instanceof String) &&
|
|
75
|
-
!(x instanceof RegExp) &&
|
|
76
|
-
!(x instanceof ArrayBuffer),
|
|
77
|
-
|
|
78
|
-
defaultHandlePromise = <P extends Promise<any>>(
|
|
79
|
-
promise: P & {
|
|
80
|
-
status?: "pending" | "fulfilled" | "rejected"
|
|
81
|
-
value?: Awaited<P>
|
|
82
|
-
reason?: unknown
|
|
83
|
-
},
|
|
84
|
-
) => {
|
|
85
|
-
switch (promise.status) {
|
|
86
|
-
case "fulfilled":
|
|
87
|
-
return promise.value as Awaited<P>
|
|
88
|
-
case "rejected":
|
|
89
|
-
throw promise.reason
|
|
90
|
-
default:
|
|
91
|
-
throw promise
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
snapCache = new WeakMap<object, [version: number, snap: unknown]>(),
|
|
96
|
-
|
|
97
|
-
createSnapshot: CreateSnapshot = <T extends object>(
|
|
98
|
-
target: T,
|
|
99
|
-
version: number,
|
|
100
|
-
handlePromise: HandlePromise = defaultHandlePromise,
|
|
101
|
-
): T => {
|
|
102
|
-
const cache = snapCache.get(target)
|
|
103
|
-
if (cache?.[0] === version) {
|
|
104
|
-
return cache[1] as T
|
|
105
|
-
}
|
|
106
|
-
const snap: any = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target))
|
|
107
|
-
markToTrack(snap, true) // mark to track
|
|
108
|
-
snapCache.set(target, [version, snap])
|
|
109
|
-
Reflect.ownKeys(target).forEach((key) => {
|
|
110
|
-
const value = Reflect.get(target, key)
|
|
111
|
-
if (refSet.has(value as object)) {
|
|
112
|
-
markToTrack(value as object, false) // mark not to track
|
|
113
|
-
snap[key] = value
|
|
114
|
-
} else if (value instanceof Promise) {
|
|
115
|
-
Object.defineProperty(snap, key, {
|
|
116
|
-
get() {
|
|
117
|
-
return handlePromise(value)
|
|
118
|
-
},
|
|
119
|
-
})
|
|
120
|
-
} else if (proxyStateMap.has(value as object)) {
|
|
121
|
-
snap[key] = snapshot(value as object, handlePromise)
|
|
122
|
-
} else {
|
|
123
|
-
snap[key] = value
|
|
124
|
-
}
|
|
125
|
-
})
|
|
126
|
-
return Object.freeze(snap)
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
proxyCache = new WeakMap<object, ProxyObject>(),
|
|
130
|
-
|
|
131
|
-
versionHolder = [1, 1] as [number, number],
|
|
132
|
-
|
|
133
|
-
proxyFunction = <T extends object>(initialObject: T): T => {
|
|
134
|
-
if (!isObject(initialObject)) {
|
|
135
|
-
throw new Error("object required")
|
|
136
|
-
}
|
|
137
|
-
const found = proxyCache.get(initialObject) as T | undefined
|
|
138
|
-
if (found) {
|
|
139
|
-
return found
|
|
140
|
-
}
|
|
141
|
-
let version = versionHolder[0]
|
|
142
|
-
const listeners = new Set<Listener>()
|
|
143
|
-
const notifyUpdate = (op: Op, nextVersion = ++versionHolder[0]) => {
|
|
144
|
-
if (version !== nextVersion) {
|
|
145
|
-
version = nextVersion
|
|
146
|
-
listeners.forEach((listener) => listener(op, nextVersion))
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
let checkVersion = versionHolder[1]
|
|
150
|
-
const ensureVersion = (nextCheckVersion = ++versionHolder[1]) => {
|
|
151
|
-
if (checkVersion !== nextCheckVersion && !listeners.size) {
|
|
152
|
-
checkVersion = nextCheckVersion
|
|
153
|
-
propProxyStates.forEach(([propProxyState]) => {
|
|
154
|
-
const propVersion = propProxyState[1](nextCheckVersion)
|
|
155
|
-
if (propVersion > version) {
|
|
156
|
-
version = propVersion
|
|
157
|
-
}
|
|
158
|
-
})
|
|
159
|
-
}
|
|
160
|
-
return version
|
|
161
|
-
}
|
|
162
|
-
const createPropListener =
|
|
163
|
-
(prop: string | symbol): Listener =>
|
|
164
|
-
(op, nextVersion) => {
|
|
165
|
-
const newOp: Op = [...op]
|
|
166
|
-
newOp[1] = [prop, ...(newOp[1] as Path)]
|
|
167
|
-
notifyUpdate(newOp, nextVersion)
|
|
168
|
-
}
|
|
169
|
-
const propProxyStates = new Map<string | symbol, readonly [ProxyState, RemoveListener?]>()
|
|
170
|
-
const addPropListener = (prop: string | symbol, propProxyState: ProxyState) => {
|
|
171
|
-
if (isDev() && propProxyStates.has(prop)) {
|
|
172
|
-
throw new Error("prop listener already exists")
|
|
173
|
-
}
|
|
174
|
-
if (listeners.size) {
|
|
175
|
-
const remove = propProxyState[3](createPropListener(prop))
|
|
176
|
-
propProxyStates.set(prop, [propProxyState, remove])
|
|
177
|
-
} else {
|
|
178
|
-
propProxyStates.set(prop, [propProxyState])
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
const removePropListener = (prop: string | symbol) => {
|
|
182
|
-
const entry = propProxyStates.get(prop)
|
|
183
|
-
if (entry) {
|
|
184
|
-
propProxyStates.delete(prop)
|
|
185
|
-
entry[1]?.()
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
const addListener = (listener: Listener) => {
|
|
189
|
-
listeners.add(listener)
|
|
190
|
-
if (listeners.size === 1) {
|
|
191
|
-
propProxyStates.forEach(([propProxyState, prevRemove], prop) => {
|
|
192
|
-
if (isDev() && prevRemove) {
|
|
193
|
-
throw new Error("remove already exists")
|
|
194
|
-
}
|
|
195
|
-
const remove = propProxyState[3](createPropListener(prop))
|
|
196
|
-
propProxyStates.set(prop, [propProxyState, remove])
|
|
197
|
-
})
|
|
198
|
-
}
|
|
199
|
-
const removeListener = () => {
|
|
200
|
-
listeners.delete(listener)
|
|
201
|
-
if (listeners.size === 0) {
|
|
202
|
-
propProxyStates.forEach(([propProxyState, remove], prop) => {
|
|
203
|
-
if (remove) {
|
|
204
|
-
remove()
|
|
205
|
-
propProxyStates.set(prop, [propProxyState])
|
|
206
|
-
}
|
|
207
|
-
})
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return removeListener
|
|
211
|
-
}
|
|
212
|
-
const baseObject = Array.isArray(initialObject) ? [] : Object.create(Object.getPrototypeOf(initialObject))
|
|
213
|
-
const handler: ProxyHandler<T> = {
|
|
214
|
-
deleteProperty(target: T, prop: string | symbol) {
|
|
215
|
-
const prevValue = Reflect.get(target, prop)
|
|
216
|
-
removePropListener(prop)
|
|
217
|
-
const deleted = Reflect.deleteProperty(target, prop)
|
|
218
|
-
if (deleted) {
|
|
219
|
-
notifyUpdate(["delete", [prop], prevValue])
|
|
220
|
-
}
|
|
221
|
-
return deleted
|
|
222
|
-
},
|
|
223
|
-
set(target: T, prop: string | symbol, value: any, receiver: object) {
|
|
224
|
-
const hasPrevValue = Reflect.has(target, prop)
|
|
225
|
-
const prevValue = Reflect.get(target, prop, receiver)
|
|
226
|
-
if (
|
|
227
|
-
hasPrevValue &&
|
|
228
|
-
(objectIs(prevValue, value) || (proxyCache.has(value) && objectIs(prevValue, proxyCache.get(value))))
|
|
229
|
-
) {
|
|
230
|
-
return true
|
|
231
|
-
}
|
|
232
|
-
removePropListener(prop)
|
|
233
|
-
if (isObject(value)) {
|
|
234
|
-
value = getUntracked(value) || value
|
|
235
|
-
}
|
|
236
|
-
let nextValue = value
|
|
237
|
-
if (Object.getOwnPropertyDescriptor(target, prop)?.set) {
|
|
238
|
-
// do nothing
|
|
239
|
-
} else if (value instanceof Promise) {
|
|
240
|
-
value
|
|
241
|
-
.then((v) => {
|
|
242
|
-
Object.assign(value, { status: "fulfilled", value: v })
|
|
243
|
-
notifyUpdate(["resolve", [prop], v])
|
|
244
|
-
})
|
|
245
|
-
.catch((e) => {
|
|
246
|
-
Object.assign(value, { status: "rejected", reason: e })
|
|
247
|
-
notifyUpdate(["reject", [prop], e])
|
|
248
|
-
})
|
|
249
|
-
} else {
|
|
250
|
-
if (!proxyStateMap.has(value) && canProxy(value)) {
|
|
251
|
-
nextValue = proxy(value)
|
|
252
|
-
}
|
|
253
|
-
const childProxyState = !refSet.has(nextValue) && proxyStateMap.get(nextValue)
|
|
254
|
-
if (childProxyState) {
|
|
255
|
-
addPropListener(prop, childProxyState)
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
Reflect.set(target, prop, nextValue, receiver)
|
|
259
|
-
notifyUpdate(["set", [prop], value, prevValue])
|
|
260
|
-
return true
|
|
261
|
-
},
|
|
262
|
-
}
|
|
263
|
-
const proxyObject = newProxy(baseObject, handler)
|
|
264
|
-
proxyCache.set(initialObject, proxyObject)
|
|
265
|
-
const proxyState: ProxyState = [baseObject, ensureVersion, createSnapshot, addListener]
|
|
266
|
-
proxyStateMap.set(proxyObject, proxyState)
|
|
267
|
-
Reflect.ownKeys(initialObject).forEach((key) => {
|
|
268
|
-
const desc = Object.getOwnPropertyDescriptor(initialObject, key) as PropertyDescriptor
|
|
269
|
-
if (desc.get || desc.set) {
|
|
270
|
-
Object.defineProperty(baseObject, key, desc)
|
|
271
|
-
} else {
|
|
272
|
-
proxyObject[key as keyof T] = initialObject[key as keyof T]
|
|
273
|
-
}
|
|
274
|
-
})
|
|
275
|
-
return proxyObject
|
|
276
|
-
},
|
|
277
|
-
) =>
|
|
278
|
-
[
|
|
279
|
-
// public functions
|
|
280
|
-
proxyFunction,
|
|
281
|
-
// shared state
|
|
282
|
-
proxyStateMap,
|
|
283
|
-
refSet,
|
|
284
|
-
// internal things
|
|
285
|
-
objectIs,
|
|
286
|
-
newProxy,
|
|
287
|
-
canProxy,
|
|
288
|
-
defaultHandlePromise,
|
|
289
|
-
snapCache,
|
|
290
|
-
createSnapshot,
|
|
291
|
-
proxyCache,
|
|
292
|
-
versionHolder,
|
|
293
|
-
] as const
|
|
294
|
-
|
|
295
|
-
const [proxyFunction] = buildProxyFunction()
|
|
296
|
-
|
|
297
|
-
export function proxy<T extends object>(initialObject: T = {} as T): T {
|
|
298
|
-
return proxyFunction(initialObject)
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
export function getVersion(proxyObject: unknown): number | undefined {
|
|
302
|
-
const proxyState = proxyStateMap.get(proxyObject as object)
|
|
303
|
-
return proxyState?.[1]()
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
export function subscribe<T extends object>(
|
|
307
|
-
proxyObject: T,
|
|
308
|
-
callback: (ops: Op[]) => void,
|
|
309
|
-
notifyInSync?: boolean,
|
|
310
|
-
): () => void {
|
|
311
|
-
const proxyState = proxyStateMap.get(proxyObject as object)
|
|
312
|
-
if (isDev() && !proxyState) {
|
|
313
|
-
console.warn("Please use proxy object")
|
|
314
|
-
}
|
|
315
|
-
let promise: Promise<void> | undefined
|
|
316
|
-
const ops: Op[] = []
|
|
317
|
-
const addListener = (proxyState as ProxyState)[3]
|
|
318
|
-
let isListenerActive = false
|
|
319
|
-
const listener: Listener = (op) => {
|
|
320
|
-
ops.push(op)
|
|
321
|
-
if (notifyInSync) {
|
|
322
|
-
callback(ops.splice(0))
|
|
323
|
-
return
|
|
324
|
-
}
|
|
325
|
-
if (!promise) {
|
|
326
|
-
promise = Promise.resolve().then(() => {
|
|
327
|
-
promise = undefined
|
|
328
|
-
if (isListenerActive) {
|
|
329
|
-
callback(ops.splice(0))
|
|
330
|
-
}
|
|
331
|
-
})
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
const removeListener = addListener(listener)
|
|
335
|
-
isListenerActive = true
|
|
336
|
-
return () => {
|
|
337
|
-
isListenerActive = false
|
|
338
|
-
removeListener()
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
export function snapshot<T extends object>(proxyObject: T, handlePromise?: HandlePromise): Snapshot<T> {
|
|
343
|
-
const proxyState = proxyStateMap.get(proxyObject as object)
|
|
344
|
-
if (isDev() && !proxyState) {
|
|
345
|
-
console.warn("Please use proxy object")
|
|
346
|
-
}
|
|
347
|
-
const [target, ensureVersion, createSnapshot] = proxyState as ProxyState
|
|
348
|
-
return createSnapshot(target, ensureVersion(), handlePromise) as Snapshot<T>
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
export function ref<T extends object>(obj: T): Ref<T> {
|
|
352
|
-
refSet.add(obj)
|
|
353
|
-
return obj as T & AsRef
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
export type Ref<T> = T & AsRef
|