@zag-js/store 0.2.3 → 0.2.5

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.d.ts CHANGED
@@ -1,23 +1,2 @@
1
- interface AsRef {
2
- $$valtioRef: true;
3
- }
4
- declare function ref<T extends object>(o: T): T & AsRef;
5
- type Path = (string | symbol)[];
6
- type Op = [op: "set", path: Path, value: unknown, prevValue: unknown] | [op: "delete", path: Path, prevValue: unknown] | [op: "resolve", path: Path, value: unknown] | [op: "reject", path: Path, error: unknown];
7
- declare function proxy<T extends object>(initialObject?: T): T;
8
- declare function getVersion(proxyObject: unknown): number | undefined;
9
- declare function subscribe<T extends object>(proxyObject: T, callback: (ops: Op[]) => void, notifyInSync?: boolean): () => void;
10
- type AnyFunction = (...args: any[]) => any;
11
- type Snapshot<T> = T extends AnyFunction ? T : T extends AsRef ? T : T extends Promise<infer V> ? Snapshot<V> : {
12
- readonly [K in keyof T]: Snapshot<T[K]>;
13
- };
14
- declare function snapshot<T extends object>(proxyObject: T): Snapshot<T>;
15
- declare function getHandler<T extends object>(proxyObject: T): any;
16
- declare function proxyWithComputed<T extends object, U extends object>(initialObject: T, computedFns: {
17
- [K in keyof U]: ((snap: Snapshot<T>) => U[K]) | {
18
- get: (snap: Snapshot<T>) => U[K];
19
- set?: (state: T, newValue: U[K]) => void;
20
- };
21
- }): T & U;
22
-
23
- export { getHandler, getVersion, proxy, proxyWithComputed, ref, snapshot, subscribe };
1
+ export { INTERNAL_Snapshot, proxy, ref, snapshot, subscribe } from 'valtio/vanilla';
2
+ export { proxyWithComputed, subscribeKey } from 'valtio/utils';
package/dist/index.js CHANGED
@@ -20,34 +20,57 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
- getHandler: () => getHandler,
24
- getVersion: () => getVersion,
25
23
  proxy: () => proxy,
26
24
  proxyWithComputed: () => proxyWithComputed,
27
25
  ref: () => ref,
28
26
  snapshot: () => snapshot,
29
- subscribe: () => subscribe
27
+ subscribe: () => subscribe,
28
+ subscribeKey: () => subscribeKey
30
29
  });
31
30
  module.exports = __toCommonJS(src_exports);
31
+
32
+ // ../../node_modules/.pnpm/valtio@1.9.0/node_modules/valtio/esm/vanilla.mjs
32
33
  var import_proxy_compare = require("proxy-compare");
33
- var __DEV__ = process.env.NODE_ENV !== "production";
34
- var VERSION = Symbol();
35
- var LISTENERS = Symbol();
36
- var SNAPSHOT = Symbol();
37
- var HANDLER = Symbol();
38
- var PROMISE_RESULT = Symbol();
39
- var PROMISE_ERROR = Symbol();
40
- var refSet = /* @__PURE__ */ new WeakSet();
41
- function ref(o) {
42
- refSet.add(o);
43
- return o;
44
- }
34
+ var import_meta = {};
45
35
  var isObject = (x) => typeof x === "object" && x !== null;
46
- var canProxy = (x) => isObject(x) && !refSet.has(x) && (Array.isArray(x) || !(Symbol.iterator in x)) && !(x instanceof WeakMap) && !(x instanceof WeakSet) && !(x instanceof Error) && !(x instanceof Number) && !(x instanceof Date) && !(x instanceof String) && !(x instanceof RegExp) && !(x instanceof ArrayBuffer);
47
- var proxyCache = /* @__PURE__ */ new WeakMap();
48
- var globalVersion = 1;
49
- var snapshotCache = /* @__PURE__ */ new WeakMap();
50
- function proxy(initialObject = {}) {
36
+ var proxyStateMap = /* @__PURE__ */ new WeakMap();
37
+ var refSet = /* @__PURE__ */ new WeakSet();
38
+ var buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) => new Proxy(target, handler), canProxy = (x) => isObject(x) && !refSet.has(x) && (Array.isArray(x) || !(Symbol.iterator in x)) && !(x instanceof WeakMap) && !(x instanceof WeakSet) && !(x instanceof Error) && !(x instanceof Number) && !(x instanceof Date) && !(x instanceof String) && !(x instanceof RegExp) && !(x instanceof ArrayBuffer), defaultHandlePromise = (promise) => {
39
+ switch (promise.status) {
40
+ case "fulfilled":
41
+ return promise.value;
42
+ case "rejected":
43
+ throw promise.reason;
44
+ default:
45
+ throw promise;
46
+ }
47
+ }, snapCache = /* @__PURE__ */ new WeakMap(), createSnapshot = (target, version, handlePromise = defaultHandlePromise) => {
48
+ const cache = snapCache.get(target);
49
+ if ((cache == null ? void 0 : cache[0]) === version) {
50
+ return cache[1];
51
+ }
52
+ const snap = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target));
53
+ (0, import_proxy_compare.markToTrack)(snap, true);
54
+ snapCache.set(target, [version, snap]);
55
+ Reflect.ownKeys(target).forEach((key) => {
56
+ const value = Reflect.get(target, key);
57
+ if (refSet.has(value)) {
58
+ (0, import_proxy_compare.markToTrack)(value, false);
59
+ snap[key] = value;
60
+ } else if (value instanceof Promise) {
61
+ Object.defineProperty(snap, key, {
62
+ get() {
63
+ return handlePromise(value);
64
+ }
65
+ });
66
+ } else if (proxyStateMap.has(value)) {
67
+ snap[key] = snapshot(value, handlePromise);
68
+ } else {
69
+ snap[key] = value;
70
+ }
71
+ });
72
+ return Object.freeze(snap);
73
+ }, proxyCache = /* @__PURE__ */ new WeakMap(), versionHolder = [1, 1], proxyFunction2 = (initialObject) => {
51
74
  if (!isObject(initialObject)) {
52
75
  throw new Error("object required");
53
76
  }
@@ -55,143 +78,139 @@ function proxy(initialObject = {}) {
55
78
  if (found) {
56
79
  return found;
57
80
  }
58
- let version = globalVersion;
81
+ let version = versionHolder[0];
59
82
  const listeners = /* @__PURE__ */ new Set();
60
- const notifyUpdate = (op, nextVersion = ++globalVersion) => {
83
+ const notifyUpdate = (op, nextVersion = ++versionHolder[0]) => {
61
84
  if (version !== nextVersion) {
62
85
  version = nextVersion;
63
86
  listeners.forEach((listener) => listener(op, nextVersion));
64
87
  }
65
88
  };
66
- const propListeners = /* @__PURE__ */ new Map();
67
- const getPropListener = (prop) => {
68
- let propListener = propListeners.get(prop);
69
- if (!propListener) {
70
- propListener = (op, nextVersion) => {
71
- const newOp = [...op];
72
- newOp[1] = [prop, ...newOp[1]];
73
- notifyUpdate(newOp, nextVersion);
74
- };
75
- propListeners.set(prop, propListener);
89
+ let checkVersion = versionHolder[1];
90
+ const ensureVersion = (nextCheckVersion = ++versionHolder[1]) => {
91
+ if (checkVersion !== nextCheckVersion && !listeners.size) {
92
+ checkVersion = nextCheckVersion;
93
+ propProxyStates.forEach(([propProxyState]) => {
94
+ const propVersion = propProxyState[1](nextCheckVersion);
95
+ if (propVersion > version) {
96
+ version = propVersion;
97
+ }
98
+ });
76
99
  }
77
- return propListener;
100
+ return version;
78
101
  };
79
- const popPropListener = (prop) => {
80
- const propListener = propListeners.get(prop);
81
- propListeners.delete(prop);
82
- return propListener;
102
+ const createPropListener = (prop) => (op, nextVersion) => {
103
+ const newOp = [...op];
104
+ newOp[1] = [prop, ...newOp[1]];
105
+ notifyUpdate(newOp, nextVersion);
106
+ };
107
+ const propProxyStates = /* @__PURE__ */ new Map();
108
+ const addPropListener = (prop, propProxyState) => {
109
+ if ((import_meta.env && import_meta.env.MODE) !== "production" && propProxyStates.has(prop)) {
110
+ throw new Error("prop listener already exists");
111
+ }
112
+ if (listeners.size) {
113
+ const remove = propProxyState[3](createPropListener(prop));
114
+ propProxyStates.set(prop, [propProxyState, remove]);
115
+ } else {
116
+ propProxyStates.set(prop, [propProxyState]);
117
+ }
83
118
  };
84
- const createSnapshot = (target, receiver) => {
85
- const cache = snapshotCache.get(receiver);
86
- if ((cache == null ? void 0 : cache[0]) === version) {
87
- return cache[1];
119
+ const removePropListener = (prop) => {
120
+ var _a;
121
+ const entry = propProxyStates.get(prop);
122
+ if (entry) {
123
+ propProxyStates.delete(prop);
124
+ (_a = entry[1]) == null ? void 0 : _a.call(entry);
88
125
  }
89
- const snapshot2 = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target));
90
- (0, import_proxy_compare.markToTrack)(snapshot2, true);
91
- snapshotCache.set(receiver, [version, snapshot2]);
92
- Reflect.ownKeys(target).forEach((key) => {
93
- const value = Reflect.get(target, key, receiver);
94
- if (refSet.has(value)) {
95
- (0, import_proxy_compare.markToTrack)(value, false);
96
- snapshot2[key] = value;
97
- } else if (value instanceof Promise) {
98
- if (PROMISE_RESULT in value) {
99
- snapshot2[key] = value[PROMISE_RESULT];
100
- } else {
101
- const errorOrPromise = value[PROMISE_ERROR] || value;
102
- Object.defineProperty(snapshot2, key, {
103
- get() {
104
- if (PROMISE_RESULT in value) {
105
- return value[PROMISE_RESULT];
106
- }
107
- throw errorOrPromise;
108
- }
109
- });
126
+ };
127
+ const addListener = (listener) => {
128
+ listeners.add(listener);
129
+ if (listeners.size === 1) {
130
+ propProxyStates.forEach(([propProxyState, prevRemove], prop) => {
131
+ if ((import_meta.env && import_meta.env.MODE) !== "production" && prevRemove) {
132
+ throw new Error("remove already exists");
110
133
  }
111
- } else if (value == null ? void 0 : value[LISTENERS]) {
112
- snapshot2[key] = value[SNAPSHOT];
113
- } else {
114
- snapshot2[key] = value;
134
+ const remove = propProxyState[3](createPropListener(prop));
135
+ propProxyStates.set(prop, [propProxyState, remove]);
136
+ });
137
+ }
138
+ const removeListener = () => {
139
+ listeners.delete(listener);
140
+ if (listeners.size === 0) {
141
+ propProxyStates.forEach(([propProxyState, remove], prop) => {
142
+ if (remove) {
143
+ remove();
144
+ propProxyStates.set(prop, [propProxyState]);
145
+ }
146
+ });
115
147
  }
116
- });
117
- Object.freeze(snapshot2);
118
- return snapshot2;
148
+ };
149
+ return removeListener;
119
150
  };
120
151
  const baseObject = Array.isArray(initialObject) ? [] : Object.create(Object.getPrototypeOf(initialObject));
121
152
  const handler = {
122
- get(target, prop, receiver) {
123
- if (prop === VERSION) {
124
- return version;
125
- }
126
- if (prop === LISTENERS) {
127
- return listeners;
128
- }
129
- if (prop === SNAPSHOT) {
130
- return createSnapshot(target, receiver);
131
- }
132
- if (prop === HANDLER) {
133
- return handler;
134
- }
135
- return Reflect.get(target, prop, receiver);
136
- },
137
153
  deleteProperty(target, prop) {
138
154
  const prevValue = Reflect.get(target, prop);
139
- const childListeners = prevValue == null ? void 0 : prevValue[LISTENERS];
140
- if (childListeners) {
141
- childListeners.delete(popPropListener(prop));
142
- }
155
+ removePropListener(prop);
143
156
  const deleted = Reflect.deleteProperty(target, prop);
144
157
  if (deleted) {
145
158
  notifyUpdate(["delete", [prop], prevValue]);
146
159
  }
147
160
  return deleted;
148
161
  },
149
- is: Object.is,
150
- canProxy,
151
162
  set(target, prop, value, receiver) {
152
163
  var _a;
153
164
  const hasPrevValue = Reflect.has(target, prop);
154
165
  const prevValue = Reflect.get(target, prop, receiver);
155
- if (hasPrevValue && this.is(prevValue, value)) {
166
+ if (hasPrevValue && objectIs(prevValue, value)) {
156
167
  return true;
157
168
  }
158
- const childListeners = prevValue == null ? void 0 : prevValue[LISTENERS];
159
- if (childListeners) {
160
- childListeners.delete(popPropListener(prop));
161
- }
169
+ removePropListener(prop);
162
170
  if (isObject(value)) {
163
171
  value = (0, import_proxy_compare.getUntracked)(value) || value;
164
172
  }
165
- let nextValue;
166
- if ((_a = Object.getOwnPropertyDescriptor(target, prop)) == null ? void 0 : _a.set) {
167
- nextValue = value;
168
- } else if (value instanceof Promise) {
169
- nextValue = value.then((v) => {
170
- nextValue[PROMISE_RESULT] = v;
173
+ let nextValue = value;
174
+ if ((_a = Object.getOwnPropertyDescriptor(target, prop)) == null ? void 0 : _a.set)
175
+ ;
176
+ else if (value instanceof Promise) {
177
+ value.then((v) => {
178
+ value.status = "fulfilled";
179
+ value.value = v;
171
180
  notifyUpdate(["resolve", [prop], v]);
172
- return v;
173
181
  }).catch((e) => {
174
- nextValue[PROMISE_ERROR] = e;
182
+ value.status = "rejected";
183
+ value.reason = e;
175
184
  notifyUpdate(["reject", [prop], e]);
176
185
  });
177
- } else if (value == null ? void 0 : value[LISTENERS]) {
178
- nextValue = value;
179
- nextValue[LISTENERS].add(getPropListener(prop));
180
- } else if (this.canProxy(value)) {
181
- nextValue = proxy(value);
182
- nextValue[LISTENERS].add(getPropListener(prop));
183
186
  } else {
184
- nextValue = value;
187
+ if (!proxyStateMap.has(value) && canProxy(value)) {
188
+ nextValue = proxy(value);
189
+ }
190
+ const childProxyState = !refSet.has(nextValue) && proxyStateMap.get(nextValue);
191
+ if (childProxyState) {
192
+ addPropListener(prop, childProxyState);
193
+ }
185
194
  }
186
195
  Reflect.set(target, prop, nextValue, receiver);
187
196
  notifyUpdate(["set", [prop], value, prevValue]);
188
197
  return true;
189
198
  }
190
199
  };
191
- const proxyObject = new Proxy(baseObject, handler);
200
+ const proxyObject = newProxy(baseObject, handler);
192
201
  proxyCache.set(initialObject, proxyObject);
202
+ const proxyState = [
203
+ baseObject,
204
+ ensureVersion,
205
+ createSnapshot,
206
+ addListener
207
+ ];
208
+ proxyStateMap.set(proxyObject, proxyState);
193
209
  Reflect.ownKeys(initialObject).forEach((key) => {
194
- const desc = Object.getOwnPropertyDescriptor(initialObject, key);
210
+ const desc = Object.getOwnPropertyDescriptor(
211
+ initialObject,
212
+ key
213
+ );
195
214
  if (desc.get || desc.set) {
196
215
  Object.defineProperty(baseObject, key, desc);
197
216
  } else {
@@ -199,16 +218,32 @@ function proxy(initialObject = {}) {
199
218
  }
200
219
  });
201
220
  return proxyObject;
202
- }
203
- function getVersion(proxyObject) {
204
- return isObject(proxyObject) ? proxyObject[VERSION] : void 0;
221
+ }) => [
222
+ proxyFunction2,
223
+ proxyStateMap,
224
+ refSet,
225
+ objectIs,
226
+ newProxy,
227
+ canProxy,
228
+ defaultHandlePromise,
229
+ snapCache,
230
+ createSnapshot,
231
+ proxyCache,
232
+ versionHolder
233
+ ];
234
+ var [proxyFunction] = buildProxyFunction();
235
+ function proxy(initialObject = {}) {
236
+ return proxyFunction(initialObject);
205
237
  }
206
238
  function subscribe(proxyObject, callback, notifyInSync) {
207
- if (__DEV__ && !(proxyObject == null ? void 0 : proxyObject[LISTENERS])) {
239
+ const proxyState = proxyStateMap.get(proxyObject);
240
+ if ((import_meta.env && import_meta.env.MODE) !== "production" && !proxyState) {
208
241
  console.warn("Please use proxy object");
209
242
  }
210
243
  let promise;
211
244
  const ops = [];
245
+ const addListener = proxyState[3];
246
+ let isListenerActive = false;
212
247
  const listener = (op) => {
213
248
  ops.push(op);
214
249
  if (notifyInSync) {
@@ -218,30 +253,48 @@ function subscribe(proxyObject, callback, notifyInSync) {
218
253
  if (!promise) {
219
254
  promise = Promise.resolve().then(() => {
220
255
  promise = void 0;
221
- callback(ops.splice(0));
256
+ if (isListenerActive) {
257
+ callback(ops.splice(0));
258
+ }
222
259
  });
223
260
  }
224
261
  };
225
- proxyObject[LISTENERS].add(listener);
262
+ const removeListener = addListener(listener);
263
+ isListenerActive = true;
226
264
  return () => {
227
- ;
228
- proxyObject[LISTENERS].delete(listener);
265
+ isListenerActive = false;
266
+ removeListener();
229
267
  };
230
268
  }
231
- function snapshot(proxyObject) {
232
- if (__DEV__ && !(proxyObject == null ? void 0 : proxyObject[SNAPSHOT])) {
269
+ function snapshot(proxyObject, handlePromise) {
270
+ const proxyState = proxyStateMap.get(proxyObject);
271
+ if ((import_meta.env && import_meta.env.MODE) !== "production" && !proxyState) {
233
272
  console.warn("Please use proxy object");
234
273
  }
235
- return proxyObject[SNAPSHOT];
274
+ const [target, ensureVersion, createSnapshot] = proxyState;
275
+ return createSnapshot(target, ensureVersion(), handlePromise);
236
276
  }
237
- function getHandler(proxyObject) {
238
- if (__DEV__ && !(proxyObject == null ? void 0 : proxyObject[HANDLER])) {
239
- console.warn("Please use proxy object");
240
- }
241
- return proxyObject[HANDLER];
277
+ function ref(obj) {
278
+ refSet.add(obj);
279
+ return obj;
280
+ }
281
+
282
+ // ../../node_modules/.pnpm/valtio@1.9.0/node_modules/valtio/esm/vanilla/utils.mjs
283
+ function subscribeKey(proxyObject, key, callback, notifyInSync) {
284
+ let prevValue = proxyObject[key];
285
+ return subscribe(
286
+ proxyObject,
287
+ () => {
288
+ const nextValue = proxyObject[key];
289
+ if (!Object.is(prevValue, nextValue)) {
290
+ callback(prevValue = nextValue);
291
+ }
292
+ },
293
+ notifyInSync
294
+ );
242
295
  }
296
+ var DEVTOOLS = Symbol();
243
297
  function proxyWithComputed(initialObject, computedFns) {
244
- ;
245
298
  Object.keys(computedFns).forEach((key) => {
246
299
  if (Object.getOwnPropertyDescriptor(initialObject, key)) {
247
300
  throw new Error("object property already defined");
@@ -260,11 +313,10 @@ function proxyWithComputed(initialObject, computedFns) {
260
313
  }
261
314
  // Annotate the CommonJS export names for ESM import in node:
262
315
  0 && (module.exports = {
263
- getHandler,
264
- getVersion,
265
316
  proxy,
266
317
  proxyWithComputed,
267
318
  ref,
268
319
  snapshot,
269
- subscribe
320
+ subscribe,
321
+ subscribeKey
270
322
  });
package/dist/index.mjs CHANGED
@@ -1,23 +1,44 @@
1
- // src/index.ts
2
- import { getUntracked, markToTrack } from "proxy-compare";
3
- var __DEV__ = process.env.NODE_ENV !== "production";
4
- var VERSION = Symbol();
5
- var LISTENERS = Symbol();
6
- var SNAPSHOT = Symbol();
7
- var HANDLER = Symbol();
8
- var PROMISE_RESULT = Symbol();
9
- var PROMISE_ERROR = Symbol();
10
- var refSet = /* @__PURE__ */ new WeakSet();
11
- function ref(o) {
12
- refSet.add(o);
13
- return o;
14
- }
1
+ // ../../node_modules/.pnpm/valtio@1.9.0/node_modules/valtio/esm/vanilla.mjs
2
+ import { markToTrack, getUntracked } from "proxy-compare";
15
3
  var isObject = (x) => typeof x === "object" && x !== null;
16
- var canProxy = (x) => isObject(x) && !refSet.has(x) && (Array.isArray(x) || !(Symbol.iterator in x)) && !(x instanceof WeakMap) && !(x instanceof WeakSet) && !(x instanceof Error) && !(x instanceof Number) && !(x instanceof Date) && !(x instanceof String) && !(x instanceof RegExp) && !(x instanceof ArrayBuffer);
17
- var proxyCache = /* @__PURE__ */ new WeakMap();
18
- var globalVersion = 1;
19
- var snapshotCache = /* @__PURE__ */ new WeakMap();
20
- function proxy(initialObject = {}) {
4
+ var proxyStateMap = /* @__PURE__ */ new WeakMap();
5
+ var refSet = /* @__PURE__ */ new WeakSet();
6
+ var buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) => new Proxy(target, handler), canProxy = (x) => isObject(x) && !refSet.has(x) && (Array.isArray(x) || !(Symbol.iterator in x)) && !(x instanceof WeakMap) && !(x instanceof WeakSet) && !(x instanceof Error) && !(x instanceof Number) && !(x instanceof Date) && !(x instanceof String) && !(x instanceof RegExp) && !(x instanceof ArrayBuffer), defaultHandlePromise = (promise) => {
7
+ switch (promise.status) {
8
+ case "fulfilled":
9
+ return promise.value;
10
+ case "rejected":
11
+ throw promise.reason;
12
+ default:
13
+ throw promise;
14
+ }
15
+ }, snapCache = /* @__PURE__ */ new WeakMap(), createSnapshot = (target, version, handlePromise = defaultHandlePromise) => {
16
+ const cache = snapCache.get(target);
17
+ if ((cache == null ? void 0 : cache[0]) === version) {
18
+ return cache[1];
19
+ }
20
+ const snap = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target));
21
+ markToTrack(snap, true);
22
+ snapCache.set(target, [version, snap]);
23
+ Reflect.ownKeys(target).forEach((key) => {
24
+ const value = Reflect.get(target, key);
25
+ if (refSet.has(value)) {
26
+ markToTrack(value, false);
27
+ snap[key] = value;
28
+ } else if (value instanceof Promise) {
29
+ Object.defineProperty(snap, key, {
30
+ get() {
31
+ return handlePromise(value);
32
+ }
33
+ });
34
+ } else if (proxyStateMap.has(value)) {
35
+ snap[key] = snapshot(value, handlePromise);
36
+ } else {
37
+ snap[key] = value;
38
+ }
39
+ });
40
+ return Object.freeze(snap);
41
+ }, proxyCache = /* @__PURE__ */ new WeakMap(), versionHolder = [1, 1], proxyFunction2 = (initialObject) => {
21
42
  if (!isObject(initialObject)) {
22
43
  throw new Error("object required");
23
44
  }
@@ -25,143 +46,139 @@ function proxy(initialObject = {}) {
25
46
  if (found) {
26
47
  return found;
27
48
  }
28
- let version = globalVersion;
49
+ let version = versionHolder[0];
29
50
  const listeners = /* @__PURE__ */ new Set();
30
- const notifyUpdate = (op, nextVersion = ++globalVersion) => {
51
+ const notifyUpdate = (op, nextVersion = ++versionHolder[0]) => {
31
52
  if (version !== nextVersion) {
32
53
  version = nextVersion;
33
54
  listeners.forEach((listener) => listener(op, nextVersion));
34
55
  }
35
56
  };
36
- const propListeners = /* @__PURE__ */ new Map();
37
- const getPropListener = (prop) => {
38
- let propListener = propListeners.get(prop);
39
- if (!propListener) {
40
- propListener = (op, nextVersion) => {
41
- const newOp = [...op];
42
- newOp[1] = [prop, ...newOp[1]];
43
- notifyUpdate(newOp, nextVersion);
44
- };
45
- propListeners.set(prop, propListener);
57
+ let checkVersion = versionHolder[1];
58
+ const ensureVersion = (nextCheckVersion = ++versionHolder[1]) => {
59
+ if (checkVersion !== nextCheckVersion && !listeners.size) {
60
+ checkVersion = nextCheckVersion;
61
+ propProxyStates.forEach(([propProxyState]) => {
62
+ const propVersion = propProxyState[1](nextCheckVersion);
63
+ if (propVersion > version) {
64
+ version = propVersion;
65
+ }
66
+ });
46
67
  }
47
- return propListener;
68
+ return version;
48
69
  };
49
- const popPropListener = (prop) => {
50
- const propListener = propListeners.get(prop);
51
- propListeners.delete(prop);
52
- return propListener;
70
+ const createPropListener = (prop) => (op, nextVersion) => {
71
+ const newOp = [...op];
72
+ newOp[1] = [prop, ...newOp[1]];
73
+ notifyUpdate(newOp, nextVersion);
74
+ };
75
+ const propProxyStates = /* @__PURE__ */ new Map();
76
+ const addPropListener = (prop, propProxyState) => {
77
+ if ((import.meta.env && import.meta.env.MODE) !== "production" && propProxyStates.has(prop)) {
78
+ throw new Error("prop listener already exists");
79
+ }
80
+ if (listeners.size) {
81
+ const remove = propProxyState[3](createPropListener(prop));
82
+ propProxyStates.set(prop, [propProxyState, remove]);
83
+ } else {
84
+ propProxyStates.set(prop, [propProxyState]);
85
+ }
53
86
  };
54
- const createSnapshot = (target, receiver) => {
55
- const cache = snapshotCache.get(receiver);
56
- if ((cache == null ? void 0 : cache[0]) === version) {
57
- return cache[1];
87
+ const removePropListener = (prop) => {
88
+ var _a;
89
+ const entry = propProxyStates.get(prop);
90
+ if (entry) {
91
+ propProxyStates.delete(prop);
92
+ (_a = entry[1]) == null ? void 0 : _a.call(entry);
58
93
  }
59
- const snapshot2 = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target));
60
- markToTrack(snapshot2, true);
61
- snapshotCache.set(receiver, [version, snapshot2]);
62
- Reflect.ownKeys(target).forEach((key) => {
63
- const value = Reflect.get(target, key, receiver);
64
- if (refSet.has(value)) {
65
- markToTrack(value, false);
66
- snapshot2[key] = value;
67
- } else if (value instanceof Promise) {
68
- if (PROMISE_RESULT in value) {
69
- snapshot2[key] = value[PROMISE_RESULT];
70
- } else {
71
- const errorOrPromise = value[PROMISE_ERROR] || value;
72
- Object.defineProperty(snapshot2, key, {
73
- get() {
74
- if (PROMISE_RESULT in value) {
75
- return value[PROMISE_RESULT];
76
- }
77
- throw errorOrPromise;
78
- }
79
- });
94
+ };
95
+ const addListener = (listener) => {
96
+ listeners.add(listener);
97
+ if (listeners.size === 1) {
98
+ propProxyStates.forEach(([propProxyState, prevRemove], prop) => {
99
+ if ((import.meta.env && import.meta.env.MODE) !== "production" && prevRemove) {
100
+ throw new Error("remove already exists");
80
101
  }
81
- } else if (value == null ? void 0 : value[LISTENERS]) {
82
- snapshot2[key] = value[SNAPSHOT];
83
- } else {
84
- snapshot2[key] = value;
102
+ const remove = propProxyState[3](createPropListener(prop));
103
+ propProxyStates.set(prop, [propProxyState, remove]);
104
+ });
105
+ }
106
+ const removeListener = () => {
107
+ listeners.delete(listener);
108
+ if (listeners.size === 0) {
109
+ propProxyStates.forEach(([propProxyState, remove], prop) => {
110
+ if (remove) {
111
+ remove();
112
+ propProxyStates.set(prop, [propProxyState]);
113
+ }
114
+ });
85
115
  }
86
- });
87
- Object.freeze(snapshot2);
88
- return snapshot2;
116
+ };
117
+ return removeListener;
89
118
  };
90
119
  const baseObject = Array.isArray(initialObject) ? [] : Object.create(Object.getPrototypeOf(initialObject));
91
120
  const handler = {
92
- get(target, prop, receiver) {
93
- if (prop === VERSION) {
94
- return version;
95
- }
96
- if (prop === LISTENERS) {
97
- return listeners;
98
- }
99
- if (prop === SNAPSHOT) {
100
- return createSnapshot(target, receiver);
101
- }
102
- if (prop === HANDLER) {
103
- return handler;
104
- }
105
- return Reflect.get(target, prop, receiver);
106
- },
107
121
  deleteProperty(target, prop) {
108
122
  const prevValue = Reflect.get(target, prop);
109
- const childListeners = prevValue == null ? void 0 : prevValue[LISTENERS];
110
- if (childListeners) {
111
- childListeners.delete(popPropListener(prop));
112
- }
123
+ removePropListener(prop);
113
124
  const deleted = Reflect.deleteProperty(target, prop);
114
125
  if (deleted) {
115
126
  notifyUpdate(["delete", [prop], prevValue]);
116
127
  }
117
128
  return deleted;
118
129
  },
119
- is: Object.is,
120
- canProxy,
121
130
  set(target, prop, value, receiver) {
122
131
  var _a;
123
132
  const hasPrevValue = Reflect.has(target, prop);
124
133
  const prevValue = Reflect.get(target, prop, receiver);
125
- if (hasPrevValue && this.is(prevValue, value)) {
134
+ if (hasPrevValue && objectIs(prevValue, value)) {
126
135
  return true;
127
136
  }
128
- const childListeners = prevValue == null ? void 0 : prevValue[LISTENERS];
129
- if (childListeners) {
130
- childListeners.delete(popPropListener(prop));
131
- }
137
+ removePropListener(prop);
132
138
  if (isObject(value)) {
133
139
  value = getUntracked(value) || value;
134
140
  }
135
- let nextValue;
136
- if ((_a = Object.getOwnPropertyDescriptor(target, prop)) == null ? void 0 : _a.set) {
137
- nextValue = value;
138
- } else if (value instanceof Promise) {
139
- nextValue = value.then((v) => {
140
- nextValue[PROMISE_RESULT] = v;
141
+ let nextValue = value;
142
+ if ((_a = Object.getOwnPropertyDescriptor(target, prop)) == null ? void 0 : _a.set)
143
+ ;
144
+ else if (value instanceof Promise) {
145
+ value.then((v) => {
146
+ value.status = "fulfilled";
147
+ value.value = v;
141
148
  notifyUpdate(["resolve", [prop], v]);
142
- return v;
143
149
  }).catch((e) => {
144
- nextValue[PROMISE_ERROR] = e;
150
+ value.status = "rejected";
151
+ value.reason = e;
145
152
  notifyUpdate(["reject", [prop], e]);
146
153
  });
147
- } else if (value == null ? void 0 : value[LISTENERS]) {
148
- nextValue = value;
149
- nextValue[LISTENERS].add(getPropListener(prop));
150
- } else if (this.canProxy(value)) {
151
- nextValue = proxy(value);
152
- nextValue[LISTENERS].add(getPropListener(prop));
153
154
  } else {
154
- nextValue = value;
155
+ if (!proxyStateMap.has(value) && canProxy(value)) {
156
+ nextValue = proxy(value);
157
+ }
158
+ const childProxyState = !refSet.has(nextValue) && proxyStateMap.get(nextValue);
159
+ if (childProxyState) {
160
+ addPropListener(prop, childProxyState);
161
+ }
155
162
  }
156
163
  Reflect.set(target, prop, nextValue, receiver);
157
164
  notifyUpdate(["set", [prop], value, prevValue]);
158
165
  return true;
159
166
  }
160
167
  };
161
- const proxyObject = new Proxy(baseObject, handler);
168
+ const proxyObject = newProxy(baseObject, handler);
162
169
  proxyCache.set(initialObject, proxyObject);
170
+ const proxyState = [
171
+ baseObject,
172
+ ensureVersion,
173
+ createSnapshot,
174
+ addListener
175
+ ];
176
+ proxyStateMap.set(proxyObject, proxyState);
163
177
  Reflect.ownKeys(initialObject).forEach((key) => {
164
- const desc = Object.getOwnPropertyDescriptor(initialObject, key);
178
+ const desc = Object.getOwnPropertyDescriptor(
179
+ initialObject,
180
+ key
181
+ );
165
182
  if (desc.get || desc.set) {
166
183
  Object.defineProperty(baseObject, key, desc);
167
184
  } else {
@@ -169,16 +186,32 @@ function proxy(initialObject = {}) {
169
186
  }
170
187
  });
171
188
  return proxyObject;
172
- }
173
- function getVersion(proxyObject) {
174
- return isObject(proxyObject) ? proxyObject[VERSION] : void 0;
189
+ }) => [
190
+ proxyFunction2,
191
+ proxyStateMap,
192
+ refSet,
193
+ objectIs,
194
+ newProxy,
195
+ canProxy,
196
+ defaultHandlePromise,
197
+ snapCache,
198
+ createSnapshot,
199
+ proxyCache,
200
+ versionHolder
201
+ ];
202
+ var [proxyFunction] = buildProxyFunction();
203
+ function proxy(initialObject = {}) {
204
+ return proxyFunction(initialObject);
175
205
  }
176
206
  function subscribe(proxyObject, callback, notifyInSync) {
177
- if (__DEV__ && !(proxyObject == null ? void 0 : proxyObject[LISTENERS])) {
207
+ const proxyState = proxyStateMap.get(proxyObject);
208
+ if ((import.meta.env && import.meta.env.MODE) !== "production" && !proxyState) {
178
209
  console.warn("Please use proxy object");
179
210
  }
180
211
  let promise;
181
212
  const ops = [];
213
+ const addListener = proxyState[3];
214
+ let isListenerActive = false;
182
215
  const listener = (op) => {
183
216
  ops.push(op);
184
217
  if (notifyInSync) {
@@ -188,30 +221,48 @@ function subscribe(proxyObject, callback, notifyInSync) {
188
221
  if (!promise) {
189
222
  promise = Promise.resolve().then(() => {
190
223
  promise = void 0;
191
- callback(ops.splice(0));
224
+ if (isListenerActive) {
225
+ callback(ops.splice(0));
226
+ }
192
227
  });
193
228
  }
194
229
  };
195
- proxyObject[LISTENERS].add(listener);
230
+ const removeListener = addListener(listener);
231
+ isListenerActive = true;
196
232
  return () => {
197
- ;
198
- proxyObject[LISTENERS].delete(listener);
233
+ isListenerActive = false;
234
+ removeListener();
199
235
  };
200
236
  }
201
- function snapshot(proxyObject) {
202
- if (__DEV__ && !(proxyObject == null ? void 0 : proxyObject[SNAPSHOT])) {
237
+ function snapshot(proxyObject, handlePromise) {
238
+ const proxyState = proxyStateMap.get(proxyObject);
239
+ if ((import.meta.env && import.meta.env.MODE) !== "production" && !proxyState) {
203
240
  console.warn("Please use proxy object");
204
241
  }
205
- return proxyObject[SNAPSHOT];
242
+ const [target, ensureVersion, createSnapshot] = proxyState;
243
+ return createSnapshot(target, ensureVersion(), handlePromise);
206
244
  }
207
- function getHandler(proxyObject) {
208
- if (__DEV__ && !(proxyObject == null ? void 0 : proxyObject[HANDLER])) {
209
- console.warn("Please use proxy object");
210
- }
211
- return proxyObject[HANDLER];
245
+ function ref(obj) {
246
+ refSet.add(obj);
247
+ return obj;
248
+ }
249
+
250
+ // ../../node_modules/.pnpm/valtio@1.9.0/node_modules/valtio/esm/vanilla/utils.mjs
251
+ function subscribeKey(proxyObject, key, callback, notifyInSync) {
252
+ let prevValue = proxyObject[key];
253
+ return subscribe(
254
+ proxyObject,
255
+ () => {
256
+ const nextValue = proxyObject[key];
257
+ if (!Object.is(prevValue, nextValue)) {
258
+ callback(prevValue = nextValue);
259
+ }
260
+ },
261
+ notifyInSync
262
+ );
212
263
  }
264
+ var DEVTOOLS = Symbol();
213
265
  function proxyWithComputed(initialObject, computedFns) {
214
- ;
215
266
  Object.keys(computedFns).forEach((key) => {
216
267
  if (Object.getOwnPropertyDescriptor(initialObject, key)) {
217
268
  throw new Error("object property already defined");
@@ -229,11 +280,10 @@ function proxyWithComputed(initialObject, computedFns) {
229
280
  return proxyObject;
230
281
  }
231
282
  export {
232
- getHandler,
233
- getVersion,
234
283
  proxy,
235
284
  proxyWithComputed,
236
285
  ref,
237
286
  snapshot,
238
- subscribe
287
+ subscribe,
288
+ subscribeKey
239
289
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/store",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "The reactive store package for zag machines",
5
5
  "keywords": [
6
6
  "js",
@@ -28,7 +28,8 @@
28
28
  "clean-package": "../../clean-package.config.json",
29
29
  "main": "dist/index.js",
30
30
  "devDependencies": {
31
- "clean-package": "2.2.0"
31
+ "clean-package": "2.2.0",
32
+ "valtio": "^1.9.0"
32
33
  },
33
34
  "module": "dist/index.mjs",
34
35
  "types": "dist/index.d.ts",