@zag-js/store 0.70.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 CHANGED
@@ -1,33 +1,6 @@
1
- "use strict";
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
- // src/index.ts
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
- (0, import_proxy_compare.markToTrack)(snap, true);
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
- (0, import_proxy_compare.markToTrack)(value, false);
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 = (0, import_proxy_compare.getUntracked)(value) || 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
- // Annotate the CommonJS export names for ESM import in node:
310
- 0 && (module.exports = {
311
- makeGlobal,
312
- proxy,
313
- proxyWithComputed,
314
- ref,
315
- snapshot,
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
- export {
279
- makeGlobal,
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.70.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": "jest --config ../../../jest.config.js --rootDir tests",
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"]}
@@ -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":";AAAA,SAAS,YAAiB;AACxB,MAAI,OAAO,eAAe,YAAa,QAAO;AAC9C,MAAI,OAAO,SAAS,YAAa,QAAO;AACxC,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI,OAAO,WAAW,YAAa,QAAO;AAC5C;AAEO,SAAS,WAAc,KAAa,OAAmB;AAC5D,QAAM,IAAI,UAAU;AACpB,MAAI,CAAC,EAAG,QAAO,MAAM;AACrB,sBAAW,MAAM;AACjB,SAAO,EAAE,GAAG;AACd;;;ACVA,SAAS,cAAc,mBAAmB;AAG1C,IAAM,QAAQ,MAAM,QAAQ,IAAI,aAAa;AAC7C,IAAM,WAAW,CAAC,MAA4B,OAAO,MAAM,YAAY,MAAM;AA2C7E,IAAM,gBAAgB,WAAW,wBAAwB,MAAM,oBAAI,QAAiC,CAAC;AACrG,IAAM,SAAS,WAAW,iBAAiB,MAAM,oBAAI,QAAQ,CAAC;AAE9D,IAAM,iBAAiB,CAAC,MAAW,OAAO,MAAM,YAAY,MAAM,QAAQ,cAAc;AACxF,IAAM,eAAe,CAAC,MAAW,OAAO,MAAM,YAAY,MAAM,QAAQ,iBAAiB;AACzF,IAAM,eAAe,CAAC,MACpB,OAAO,MAAM,YAAY,MAAM,QAAQ,cAAc,KAAK,OAAO,EAAE,aAAa;AAClF,IAAM,YAAY,CAAC,MAAW,eAAe,CAAC,KAAK,aAAa,CAAC,KAAK,aAAa,CAAC;AAEpF,IAAM,qBAAqB,CACzB,WAAW,OAAO,IAElB,WAAW,CAAmB,QAAW,YAAgC,IAAI,MAAM,QAAQ,OAAO,GAElG,WAAW,CAAC,MACV,SAAS,CAAC,KACV,CAAC,OAAO,IAAI,CAAC,MACZ,MAAM,QAAQ,CAAC,KAAK,EAAE,OAAO,YAAY,OAC1C,CAAC,UAAU,CAAC,KACZ,EAAE,aAAa,YACf,EAAE,aAAa,YACf,EAAE,aAAa,UACf,EAAE,aAAa,WACf,EAAE,aAAa,SACf,EAAE,aAAa,WACf,EAAE,aAAa,WACf,EAAE,aAAa,cAEjB,uBAAuB,CACrB,YAKG;AACH,UAAQ,QAAQ,QAAQ;AAAA,IACtB,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB,KAAK;AACH,YAAM,QAAQ;AAAA,IAChB;AACE,YAAM;AAAA,EACV;AACF,GAEA,YAAY,oBAAI,QAAkD,GAElE,iBAAiC,CAC/B,QACA,SACA,gBAA+B,yBACzB;AACN,QAAM,QAAQ,UAAU,IAAI,MAAM;AAClC,MAAI,QAAQ,CAAC,MAAM,SAAS;AAC1B,WAAO,MAAM,CAAC;AAAA,EAChB;AACA,QAAM,OAAY,MAAM,QAAQ,MAAM,IAAI,CAAC,IAAI,OAAO,OAAO,OAAO,eAAe,MAAM,CAAC;AAC1F,cAAY,MAAM,IAAI;AACtB,YAAU,IAAI,QAAQ,CAAC,SAAS,IAAI,CAAC;AACrC,UAAQ,QAAQ,MAAM,EAAE,QAAQ,CAAC,QAAQ;AACvC,UAAM,QAAQ,QAAQ,IAAI,QAAQ,GAAG;AACrC,QAAI,OAAO,IAAI,KAAe,GAAG;AAC/B,kBAAY,OAAiB,KAAK;AAClC,WAAK,GAAG,IAAI;AAAA,IACd,WAAW,iBAAiB,SAAS;AACnC,aAAO,eAAe,MAAM,KAAK;AAAA,QAC/B,MAAM;AACJ,iBAAO,cAAc,KAAK;AAAA,QAC5B;AAAA,MACF,CAAC;AAAA,IACH,WAAW,cAAc,IAAI,KAAe,GAAG;AAC7C,WAAK,GAAG,IAAI,SAAS,OAAiB,aAAa;AAAA,IACrD,OAAO;AACL,WAAK,GAAG,IAAI;AAAA,IACd;AAAA,EACF,CAAC;AACD,SAAO,OAAO,OAAO,IAAI;AAC3B,GAEA,aAAa,oBAAI,QAA6B,GAE9C,gBAAgB,CAAC,GAAG,CAAC,GAErBA,iBAAgB,CAAmB,kBAAwB;AACzD,MAAI,CAAC,SAAS,aAAa,GAAG;AAC5B,UAAM,IAAI,MAAM,iBAAiB;AAAA,EACnC;AACA,QAAM,QAAQ,WAAW,IAAI,aAAa;AAC1C,MAAI,OAAO;AACT,WAAO;AAAA,EACT;AACA,MAAI,UAAU,cAAc,CAAC;AAC7B,QAAM,YAAY,oBAAI,IAAc;AACpC,QAAM,eAAe,CAAC,IAAQ,cAAc,EAAE,cAAc,CAAC,MAAM;AACjE,QAAI,YAAY,aAAa;AAC3B,gBAAU;AACV,gBAAU,QAAQ,CAAC,aAAa,SAAS,IAAI,WAAW,CAAC;AAAA,IAC3D;AAAA,EACF;AACA,MAAI,eAAe,cAAc,CAAC;AAClC,QAAM,gBAAgB,CAAC,mBAAmB,EAAE,cAAc,CAAC,MAAM;AAC/D,QAAI,iBAAiB,oBAAoB,CAAC,UAAU,MAAM;AACxD,qBAAe;AACf,sBAAgB,QAAQ,CAAC,CAAC,cAAc,MAAM;AAC5C,cAAM,cAAc,eAAe,CAAC,EAAE,gBAAgB;AACtD,YAAI,cAAc,SAAS;AACzB,oBAAU;AAAA,QACZ;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACA,QAAM,qBACJ,CAAC,SACD,CAAC,IAAI,gBAAgB;AACnB,UAAM,QAAY,CAAC,GAAG,EAAE;AACxB,UAAM,CAAC,IAAI,CAAC,MAAM,GAAI,MAAM,CAAC,CAAU;AACvC,iBAAa,OAAO,WAAW;AAAA,EACjC;AACF,QAAM,kBAAkB,oBAAI,IAA6D;AACzF,QAAM,kBAAkB,CAAC,MAAuB,mBAA+B;AAC7E,QAAI,MAAM,KAAK,gBAAgB,IAAI,IAAI,GAAG;AACxC,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,QAAI,UAAU,MAAM;AAClB,YAAM,SAAS,eAAe,CAAC,EAAE,mBAAmB,IAAI,CAAC;AACzD,sBAAgB,IAAI,MAAM,CAAC,gBAAgB,MAAM,CAAC;AAAA,IACpD,OAAO;AACL,sBAAgB,IAAI,MAAM,CAAC,cAAc,CAAC;AAAA,IAC5C;AAAA,EACF;AACA,QAAM,qBAAqB,CAAC,SAA0B;AACpD,UAAM,QAAQ,gBAAgB,IAAI,IAAI;AACtC,QAAI,OAAO;AACT,sBAAgB,OAAO,IAAI;AAC3B,YAAM,CAAC,IAAI;AAAA,IACb;AAAA,EACF;AACA,QAAM,cAAc,CAAC,aAAuB;AAC1C,cAAU,IAAI,QAAQ;AACtB,QAAI,UAAU,SAAS,GAAG;AACxB,sBAAgB,QAAQ,CAAC,CAAC,gBAAgB,UAAU,GAAG,SAAS;AAC9D,YAAI,MAAM,KAAK,YAAY;AACzB,gBAAM,IAAI,MAAM,uBAAuB;AAAA,QACzC;AACA,cAAM,SAAS,eAAe,CAAC,EAAE,mBAAmB,IAAI,CAAC;AACzD,wBAAgB,IAAI,MAAM,CAAC,gBAAgB,MAAM,CAAC;AAAA,MACpD,CAAC;AAAA,IACH;AACA,UAAM,iBAAiB,MAAM;AAC3B,gBAAU,OAAO,QAAQ;AACzB,UAAI,UAAU,SAAS,GAAG;AACxB,wBAAgB,QAAQ,CAAC,CAAC,gBAAgB,MAAM,GAAG,SAAS;AAC1D,cAAI,QAAQ;AACV,mBAAO;AACP,4BAAgB,IAAI,MAAM,CAAC,cAAc,CAAC;AAAA,UAC5C;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,QAAM,aAAa,MAAM,QAAQ,aAAa,IAAI,CAAC,IAAI,OAAO,OAAO,OAAO,eAAe,aAAa,CAAC;AACzG,QAAM,UAA2B;AAAA,IAC/B,eAAe,QAAW,MAAuB;AAC/C,YAAM,YAAY,QAAQ,IAAI,QAAQ,IAAI;AAC1C,yBAAmB,IAAI;AACvB,YAAM,UAAU,QAAQ,eAAe,QAAQ,IAAI;AACnD,UAAI,SAAS;AACX,qBAAa,CAAC,UAAU,CAAC,IAAI,GAAG,SAAS,CAAC;AAAA,MAC5C;AACA,aAAO;AAAA,IACT;AAAA,IACA,IAAI,QAAW,MAAuB,OAAY,UAAkB;AAClE,YAAM,eAAe,QAAQ,IAAI,QAAQ,IAAI;AAC7C,YAAM,YAAY,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AACpD,UACE,iBACC,SAAS,WAAW,KAAK,KAAM,WAAW,IAAI,KAAK,KAAK,SAAS,WAAW,WAAW,IAAI,KAAK,CAAC,IAClG;AACA,eAAO;AAAA,MACT;AACA,yBAAmB,IAAI;AACvB,UAAI,SAAS,KAAK,GAAG;AACnB,gBAAQ,aAAa,KAAK,KAAK;AAAA,MACjC;AACA,UAAI,YAAY;AAChB,UAAI,OAAO,yBAAyB,QAAQ,IAAI,GAAG,KAAK;AAAA,MAExD,WAAW,iBAAiB,SAAS;AACnC,cACG,KAAK,CAAC,MAAM;AACX,iBAAO,OAAO,OAAO,EAAE,QAAQ,aAAa,OAAO,EAAE,CAAC;AACtD,uBAAa,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,CAAC;AAAA,QACrC,CAAC,EACA,MAAM,CAAC,MAAM;AACZ,iBAAO,OAAO,OAAO,EAAE,QAAQ,YAAY,QAAQ,EAAE,CAAC;AACtD,uBAAa,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC;AAAA,QACpC,CAAC;AAAA,MACL,OAAO;AACL,YAAI,CAAC,cAAc,IAAI,KAAK,KAAK,SAAS,KAAK,GAAG;AAChD,sBAAY,MAAM,KAAK;AAAA,QACzB;AACA,cAAM,kBAAkB,CAAC,OAAO,IAAI,SAAS,KAAK,cAAc,IAAI,SAAS;AAC7E,YAAI,iBAAiB;AACnB,0BAAgB,MAAM,eAAe;AAAA,QACvC;AAAA,MACF;AACA,cAAQ,IAAI,QAAQ,MAAM,WAAW,QAAQ;AAC7C,mBAAa,CAAC,OAAO,CAAC,IAAI,GAAG,OAAO,SAAS,CAAC;AAC9C,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,cAAc,SAAS,YAAY,OAAO;AAChD,aAAW,IAAI,eAAe,WAAW;AACzC,QAAM,aAAyB,CAAC,YAAY,eAAe,gBAAgB,WAAW;AACtF,gBAAc,IAAI,aAAa,UAAU;AACzC,UAAQ,QAAQ,aAAa,EAAE,QAAQ,CAAC,QAAQ;AAC9C,UAAM,OAAO,OAAO,yBAAyB,eAAe,GAAG;AAC/D,QAAI,KAAK,OAAO,KAAK,KAAK;AACxB,aAAO,eAAe,YAAY,KAAK,IAAI;AAAA,IAC7C,OAAO;AACL,kBAAY,GAAc,IAAI,cAAc,GAAc;AAAA,IAC5D;AAAA,EACF,CAAC;AACD,SAAO;AACT,MAEA;AAAA;AAAA,EAEEA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEF,IAAM,CAAC,aAAa,IAAI,mBAAmB;AAEpC,SAAS,MAAwB,gBAAmB,CAAC,GAAW;AACrE,SAAO,cAAc,aAAa;AACpC;AAOO,SAAS,UACd,aACA,UACA,cACY;AACZ,QAAM,aAAa,cAAc,IAAI,WAAqB;AAC1D,MAAI,MAAM,KAAK,CAAC,YAAY;AAC1B,YAAQ,KAAK,yBAAyB;AAAA,EACxC;AACA,MAAI;AACJ,QAAM,MAAY,CAAC;AACnB,QAAM,cAAe,WAA0B,CAAC;AAChD,MAAI,mBAAmB;AACvB,QAAM,WAAqB,CAAC,OAAO;AACjC,QAAI,KAAK,EAAE;AACX,QAAI,cAAc;AAChB,eAAS,IAAI,OAAO,CAAC,CAAC;AACtB;AAAA,IACF;AACA,QAAI,CAAC,SAAS;AACZ,gBAAU,QAAQ,QAAQ,EAAE,KAAK,MAAM;AACrC,kBAAU;AACV,YAAI,kBAAkB;AACpB,mBAAS,IAAI,OAAO,CAAC,CAAC;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,QAAM,iBAAiB,YAAY,QAAQ;AAC3C,qBAAmB;AACnB,SAAO,MAAM;AACX,uBAAmB;AACnB,mBAAe;AAAA,EACjB;AACF;AAEO,SAAS,SAA2B,aAAgB,eAA4C;AACrG,QAAM,aAAa,cAAc,IAAI,WAAqB;AAC1D,MAAI,MAAM,KAAK,CAAC,YAAY;AAC1B,YAAQ,KAAK,yBAAyB;AAAA,EACxC;AACA,QAAM,CAAC,QAAQ,eAAe,cAAc,IAAI;AAChD,SAAO,eAAe,QAAQ,cAAc,GAAG,aAAa;AAC9D;AAEO,SAAS,IAAsB,KAAgB;AACpD,SAAO,IAAI,GAAG;AACd,SAAO;AACT;;;AC/VO,SAAS,kBACd,eACA,aAQA;AACA,QAAM,OAAO,OAAO,KAAK,WAAW;AACpC,OAAK,QAAQ,CAAC,QAAQ;AACpB,QAAI,OAAO,yBAAyB,eAAe,GAAG,GAAG;AACvD,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,UAAM,aAAa,YAAY,GAAG;AAClC,UAAM,EAAE,KAAK,IAAI,IAAK,OAAO,eAAe,aAAa,EAAE,KAAK,WAAW,IAAI;AAI/E,UAAM,OAA2B,CAAC;AAClC,SAAK,MAAM,MAAM,IAAI,SAAS,WAAW,CAAC;AAC1C,QAAI,KAAK;AACP,WAAK,MAAM,CAAC,aAAa,IAAI,aAAa,QAAQ;AAAA,IACpD;AACA,WAAO,eAAe,eAAe,KAAK,IAAI;AAAA,EAChD,CAAC;AACD,QAAM,cAAc,MAAM,aAAa;AACvC,SAAO;AACT;","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
@@ -1,3 +0,0 @@
1
- export { makeGlobal } from "./global"
2
- export { proxy, ref, snapshot, subscribe, type Ref, type Snapshot } from "./proxy"
3
- export { proxyWithComputed } from "./proxy-computed"
@@ -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