@coaction/pinia 1.5.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @coaction/pinia
2
2
 
3
- ![Node CI](https://github.com/unadlib/coaction/workflows/Node%20CI/badge.svg)
3
+ ![Node CI](https://github.com/coactionjs/coaction/workflows/Node%20CI/badge.svg)
4
4
  [![npm](https://img.shields.io/npm/v/@coaction/pinia.svg)](https://www.npmjs.com/package/@coaction/pinia)
5
5
  ![license](https://img.shields.io/npm/l/@coaction/pinia)
6
6
 
@@ -46,4 +46,4 @@ const useStore = create(() =>
46
46
 
47
47
  ## Documentation
48
48
 
49
- You can find the documentation [here](https://github.com/unadlib/coaction).
49
+ You can find the documentation [here](https://github.com/coactionjs/coaction).
package/dist/index.d.mts CHANGED
@@ -1,25 +1,13 @@
1
- import { StoreDefinition, StateTree, _GettersTree, DefineStoreOptions } from 'pinia';
2
- export * from 'pinia';
1
+ import { DefineStoreOptions, StateTree, StoreDefinition, _GettersTree } from "pinia";
2
+ export * from "pinia";
3
3
 
4
- type FunctionKeys<T> = {
5
- [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
6
- }[keyof T];
7
- type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
8
- type ReadonlyKeys<T> = {
9
- [K in keyof T]: Equal<{
10
- [P in K]: T[P];
11
- }, Readonly<{
12
- [P in K]: T[P];
13
- }>> extends true ? K : never;
14
- }[keyof T];
15
- type IStore<T extends object> = [
16
- string,
17
- Pick<T, Exclude<keyof T, ReadonlyKeys<T> | FunctionKeys<T>>>,
18
- {
19
- [K in ReadonlyKeys<T>]: (state: Pick<T, Exclude<keyof T, ReadonlyKeys<T> | FunctionKeys<T>>>) => T[K];
20
- },
21
- Pick<T, FunctionKeys<T>>
22
- ];
4
+ //#region \0rolldown/runtime.js
5
+ //#endregion
6
+ //#region packages/coaction-pinia/src/index.d.ts
7
+ type FunctionKeys<T> = { [K in keyof T]: T[K] extends ((...args: any[]) => any) ? K : never }[keyof T];
8
+ type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
9
+ type ReadonlyKeys<T> = { [K in keyof T]: Equal<{ [P in K]: T[P] }, Readonly<{ [P in K]: T[P] }>> extends true ? K : never }[keyof T];
10
+ type IStore<T extends object> = [string, Pick<T, Exclude<keyof T, ReadonlyKeys<T> | FunctionKeys<T>>>, { [K in ReadonlyKeys<T>]: (state: Pick<T, Exclude<keyof T, ReadonlyKeys<T> | FunctionKeys<T>>>) => T[K] }, Pick<T, FunctionKeys<T>>];
23
11
  /**
24
12
  * Bind a store to Pinia
25
13
  */
@@ -29,5 +17,8 @@ declare const bindPinia: <Id extends string, S extends StateTree = {}, G extends
29
17
  */
30
18
  declare const adapt: <T extends object>(store: StoreDefinition<IStore<T>[0], IStore<T>[1], IStore<T>[2], IStore<T>[3]>) => T;
31
19
  type PiniaStore<T extends object> = StoreDefinition<IStore<T>[0], IStore<T>[1], IStore<T>[2], IStore<T>[3]>;
32
-
33
- export { type IStore, type PiniaStore, adapt, bindPinia };
20
+ declare namespace index_d_exports {
21
+ export { IStore, PiniaStore, adapt, bindPinia };
22
+ }
23
+ //#endregion
24
+ export { IStore, PiniaStore, adapt, bindPinia };
package/dist/index.d.ts CHANGED
@@ -1,25 +1,13 @@
1
- import { StoreDefinition, StateTree, _GettersTree, DefineStoreOptions } from 'pinia';
2
- export * from 'pinia';
1
+ import { DefineStoreOptions, StateTree, StoreDefinition, _GettersTree } from "pinia";
2
+ export * from "pinia";
3
3
 
4
- type FunctionKeys<T> = {
5
- [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
6
- }[keyof T];
7
- type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
8
- type ReadonlyKeys<T> = {
9
- [K in keyof T]: Equal<{
10
- [P in K]: T[P];
11
- }, Readonly<{
12
- [P in K]: T[P];
13
- }>> extends true ? K : never;
14
- }[keyof T];
15
- type IStore<T extends object> = [
16
- string,
17
- Pick<T, Exclude<keyof T, ReadonlyKeys<T> | FunctionKeys<T>>>,
18
- {
19
- [K in ReadonlyKeys<T>]: (state: Pick<T, Exclude<keyof T, ReadonlyKeys<T> | FunctionKeys<T>>>) => T[K];
20
- },
21
- Pick<T, FunctionKeys<T>>
22
- ];
4
+ //#region \0rolldown/runtime.js
5
+ //#endregion
6
+ //#region packages/coaction-pinia/src/index.d.ts
7
+ type FunctionKeys<T> = { [K in keyof T]: T[K] extends ((...args: any[]) => any) ? K : never }[keyof T];
8
+ type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
9
+ type ReadonlyKeys<T> = { [K in keyof T]: Equal<{ [P in K]: T[P] }, Readonly<{ [P in K]: T[P] }>> extends true ? K : never }[keyof T];
10
+ type IStore<T extends object> = [string, Pick<T, Exclude<keyof T, ReadonlyKeys<T> | FunctionKeys<T>>>, { [K in ReadonlyKeys<T>]: (state: Pick<T, Exclude<keyof T, ReadonlyKeys<T> | FunctionKeys<T>>>) => T[K] }, Pick<T, FunctionKeys<T>>];
23
11
  /**
24
12
  * Bind a store to Pinia
25
13
  */
@@ -29,5 +17,8 @@ declare const bindPinia: <Id extends string, S extends StateTree = {}, G extends
29
17
  */
30
18
  declare const adapt: <T extends object>(store: StoreDefinition<IStore<T>[0], IStore<T>[1], IStore<T>[2], IStore<T>[3]>) => T;
31
19
  type PiniaStore<T extends object> = StoreDefinition<IStore<T>[0], IStore<T>[1], IStore<T>[2], IStore<T>[3]>;
32
-
33
- export { type IStore, type PiniaStore, adapt, bindPinia };
20
+ declare namespace index_d_exports {
21
+ export { IStore, PiniaStore, adapt, bindPinia };
22
+ }
23
+ //#endregion
24
+ export { IStore, PiniaStore, adapt, bindPinia };
package/dist/index.js CHANGED
@@ -1,130 +1,247 @@
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 });
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#endregion
3
+ let mutability = require("mutability");
4
+ let coaction = require("coaction");
5
+ let pinia = require("pinia");
6
+ //#region packages/coaction-pinia/src/index.ts
7
+ const instancesMap = /* @__PURE__ */ new WeakMap();
8
+ const getOwnEnumerableKeys = (value) => Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
9
+ const isUnsafeKey = (key) => typeof key === "string" && (key === "__proto__" || key === "prototype" || key === "constructor");
10
+ const isArrayIndexKey = (key) => {
11
+ if (typeof key !== "string") return false;
12
+ const index = Number(key);
13
+ return Number.isInteger(index) && index >= 0 && index < 2 ** 32 - 1 && String(index) === key;
9
14
  };
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;
15
+ const isObjectRecord = (value) => Object.prototype.toString.call(value) === "[object Object]";
16
+ const replaceMutableState = (rawState, mutableState, publicState, source) => {
17
+ const nextKeys = /* @__PURE__ */ new Set();
18
+ for (const key of getOwnEnumerableKeys(source)) {
19
+ if (isUnsafeKey(key)) continue;
20
+ if (typeof source[key] === "function") continue;
21
+ nextKeys.add(key);
22
+ }
23
+ for (const key of getOwnEnumerableKeys(rawState)) {
24
+ if (isUnsafeKey(key)) {
25
+ delete rawState[key];
26
+ delete mutableState[key];
27
+ delete publicState[key];
28
+ continue;
29
+ }
30
+ if (typeof rawState[key] === "function") continue;
31
+ if (!nextKeys.has(key)) {
32
+ delete rawState[key];
33
+ delete mutableState[key];
34
+ delete publicState[key];
35
+ }
36
+ }
37
+ const rawSeen = /* @__PURE__ */ new WeakMap();
38
+ const mutableSeen = /* @__PURE__ */ new WeakMap();
39
+ const publicSeen = /* @__PURE__ */ new WeakMap();
40
+ rawSeen.set(source, rawState);
41
+ mutableSeen.set(source, mutableState);
42
+ publicSeen.set(source, publicState);
43
+ nextKeys.forEach((key) => {
44
+ rawState[key] = (0, coaction.sanitizeReplacementState)(source[key], rawSeen);
45
+ mutableState[key] = (0, coaction.sanitizeReplacementState)(source[key], mutableSeen);
46
+ publicState[key] = (0, coaction.sanitizeReplacementState)(source[key], publicSeen);
47
+ });
17
48
  };
18
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
-
21
- // index.ts
22
- var index_exports = {};
23
- __export(index_exports, {
24
- adapt: () => adapt,
25
- bindPinia: () => bindPinia
26
- });
27
- module.exports = __toCommonJS(index_exports);
28
-
29
- // src/index.ts
30
- var src_exports = {};
31
- __export(src_exports, {
32
- adapt: () => adapt,
33
- bindPinia: () => bindPinia
34
- });
35
- var import_mutability = require("mutability");
36
- var import_coaction = require("coaction");
37
- var import_pinia = require("pinia");
38
- __reExport(src_exports, require("pinia"));
39
- var instancesMap = /* @__PURE__ */ new WeakMap();
40
- var handleStore = (store, state, _, internal) => {
41
- if (!internal.toMutableRaw) {
42
- internal.toMutableRaw = (key) => instancesMap.get(key);
43
- Object.assign(store, {
44
- subscribe: (callback) => {
45
- store._subscriptions.add(callback);
46
- return () => store._subscriptions.delete(callback);
47
- }
48
- });
49
- store._subscriptions = /* @__PURE__ */ new Set();
50
- store._destroyers = /* @__PURE__ */ new Set();
51
- const baseDestroy = store.destroy;
52
- let destroyed = false;
53
- store.destroy = () => {
54
- if (destroyed) {
55
- return;
56
- }
57
- destroyed = true;
58
- baseDestroy();
59
- store._subscriptions.clear();
60
- store._subscriptions = void 0;
61
- store._destroyers.forEach((destroy2) => destroy2());
62
- store._destroyers = void 0;
63
- };
64
- store.apply = (state2 = store.getState(), patches) => {
65
- if (!patches) {
66
- if (state2 === store.getState()) return;
67
- Object.assign(store.getState(), state2);
68
- return;
69
- }
70
- (0, import_mutability.apply)(state2, patches);
71
- };
72
- }
73
- const mutableStore = internal.toMutableRaw(state);
74
- if (!mutableStore) {
75
- throw new Error("Pinia store instance is not found");
76
- }
77
- const stopWatch = mutableStore.$subscribe((...args) => {
78
- store._subscriptions.forEach((callback) => callback(...args));
79
- });
80
- const destroy = () => {
81
- instancesMap.delete(state);
82
- stopWatch();
83
- };
84
- store._destroyers.add(destroy);
49
+ const toSnapshot = (value, visited = /* @__PURE__ */ new WeakMap()) => {
50
+ if (Array.isArray(value)) {
51
+ if (visited.has(value)) return visited.get(value);
52
+ const next = [];
53
+ next.length = value.length;
54
+ visited.set(value, next);
55
+ for (let index = 0; index < value.length; index += 1) if (Object.prototype.hasOwnProperty.call(value, index)) next[index] = toSnapshot(value[index], visited);
56
+ const source = value;
57
+ const target = next;
58
+ for (const key of getOwnEnumerableKeys(value)) {
59
+ if (isArrayIndexKey(key) || isUnsafeKey(key)) continue;
60
+ const child = source[key];
61
+ if (typeof child !== "function") target[key] = toSnapshot(child, visited);
62
+ }
63
+ return next;
64
+ }
65
+ if (typeof value === "object" && value !== null) {
66
+ if (!isObjectRecord(value)) return value;
67
+ if (visited.has(value)) return visited.get(value);
68
+ const next = {};
69
+ visited.set(value, next);
70
+ for (const key of getOwnEnumerableKeys(value)) {
71
+ if (isUnsafeKey(key)) continue;
72
+ const child = value[key];
73
+ if (typeof child !== "function") next[key] = toSnapshot(child, visited);
74
+ }
75
+ return next;
76
+ }
77
+ return value;
78
+ };
79
+ const snapshotPureState = (store) => toSnapshot(store.getPureState());
80
+ const isEqualSnapshot = (left, right, visited = /* @__PURE__ */ new WeakMap()) => {
81
+ if (Object.is(left, right)) return true;
82
+ if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
83
+ const leftIsArray = Array.isArray(left);
84
+ const rightIsArray = Array.isArray(right);
85
+ if (leftIsArray || rightIsArray) {
86
+ if (!leftIsArray || !rightIsArray || left.length !== right.length) return false;
87
+ } else if (!isObjectRecord(left) || !isObjectRecord(right)) return false;
88
+ let seenTargets = visited.get(left);
89
+ if (!seenTargets) {
90
+ seenTargets = /* @__PURE__ */ new WeakSet();
91
+ visited.set(left, seenTargets);
92
+ } else if (seenTargets.has(right)) return true;
93
+ seenTargets.add(right);
94
+ const leftRecord = left;
95
+ const rightRecord = right;
96
+ const leftKeys = getOwnEnumerableKeys(left);
97
+ const rightKeys = getOwnEnumerableKeys(right);
98
+ if (leftKeys.length !== rightKeys.length) return false;
99
+ for (const key of leftKeys) {
100
+ if (!Object.prototype.hasOwnProperty.call(rightRecord, key)) return false;
101
+ if (!isEqualSnapshot(leftRecord[key], rightRecord[key], visited)) return false;
102
+ }
103
+ return true;
104
+ };
105
+ const handleStore = (store, state, _, internal) => {
106
+ const rawState = state;
107
+ let isApplyingCoactionState = false;
108
+ let lastSnapshot;
109
+ const restoreClientState = (snapshot) => {
110
+ const mutableStore = internal.toMutableRaw(rawState);
111
+ if (!mutableStore) return;
112
+ isApplyingCoactionState = true;
113
+ try {
114
+ replaceMutableState(internal.rootState ?? rawState, mutableStore, store.getState(), snapshot);
115
+ } finally {
116
+ lastSnapshot = snapshotPureState(store);
117
+ isApplyingCoactionState = false;
118
+ }
119
+ };
120
+ const syncSharedExternalChange = () => {
121
+ const currentSnapshot = snapshotPureState(store);
122
+ if (isApplyingCoactionState) {
123
+ lastSnapshot = currentSnapshot;
124
+ return "handled";
125
+ }
126
+ if (store.share === "client" && lastSnapshot) {
127
+ if (!isEqualSnapshot(currentSnapshot, lastSnapshot)) restoreClientState(lastSnapshot);
128
+ return "ignored";
129
+ }
130
+ if (store.share === "main" && lastSnapshot) {
131
+ const rootState = internal.rootState;
132
+ internal.rootState = lastSnapshot;
133
+ try {
134
+ (0, coaction.replaceExternalStoreState)(store, internal, currentSnapshot, { syncImmutable: false });
135
+ } finally {
136
+ internal.rootState = rootState;
137
+ }
138
+ lastSnapshot = currentSnapshot;
139
+ return "handled";
140
+ }
141
+ lastSnapshot = currentSnapshot;
142
+ return "external";
143
+ };
144
+ if (!internal.toMutableRaw) {
145
+ internal.toMutableRaw = (key) => instancesMap.get(key);
146
+ Object.assign(store, { subscribe: (callback) => {
147
+ store._subscriptions.add(callback);
148
+ return () => {
149
+ store._subscriptions?.delete(callback);
150
+ };
151
+ } });
152
+ store._subscriptions = /* @__PURE__ */ new Set();
153
+ store._destroyers = /* @__PURE__ */ new Set();
154
+ const baseDestroy = store.destroy;
155
+ let destroyed = false;
156
+ store.destroy = () => {
157
+ if (destroyed) return;
158
+ destroyed = true;
159
+ store._subscriptions?.clear();
160
+ store._subscriptions = void 0;
161
+ store._destroyers?.forEach((destroy) => destroy());
162
+ store._destroyers?.clear();
163
+ store._destroyers = void 0;
164
+ baseDestroy();
165
+ };
166
+ store.apply = (nextState = store.getState(), patches) => {
167
+ isApplyingCoactionState = true;
168
+ try {
169
+ if (!patches) {
170
+ if (nextState === store.getState()) return;
171
+ replaceMutableState(internal.rootState ?? rawState, internal.toMutableRaw(rawState), store.getState(), nextState);
172
+ return;
173
+ }
174
+ (0, mutability.apply)(nextState, patches);
175
+ } finally {
176
+ lastSnapshot = snapshotPureState(store);
177
+ isApplyingCoactionState = false;
178
+ internal.notifyStateChange?.();
179
+ }
180
+ };
181
+ }
182
+ const mutableStore = internal.toMutableRaw(state);
183
+ if (!mutableStore) throw new Error("Pinia store instance is not found");
184
+ let stopWatch;
185
+ const cancelReadySubscription = (0, coaction.onStoreReady)(store, () => {
186
+ replaceMutableState(internal.rootState ?? rawState, mutableStore, store.getState(), (0, coaction.sanitizeInitialStateValue)(snapshotPureState(store)));
187
+ lastSnapshot = snapshotPureState(store);
188
+ stopWatch = mutableStore.$subscribe((...args) => {
189
+ const change = syncSharedExternalChange();
190
+ if (change === "ignored") return;
191
+ if (change === "external") internal.notifyStateChange?.();
192
+ store._subscriptions.forEach((callback) => callback(...args));
193
+ });
194
+ });
195
+ const destroy = () => {
196
+ cancelReadySubscription();
197
+ instancesMap.delete(state);
198
+ stopWatch?.();
199
+ };
200
+ store._destroyers.add(destroy);
85
201
  };
86
- var bindPinia = (0, import_coaction.createBinder)({
87
- handleStore,
88
- handleState: ((options) => {
89
- const descriptors = {};
90
- options.getters = options.getters ?? {};
91
- for (const key of Object.keys(options.getters)) {
92
- const getter = options.getters[key];
93
- if (typeof getter !== "function") {
94
- continue;
95
- }
96
- descriptors[key] = {
97
- get() {
98
- return getter.call(this, this);
99
- }
100
- };
101
- }
102
- const rawState = Object.defineProperties(
103
- {
104
- ...options.state?.(),
105
- ...options.actions
106
- },
107
- descriptors
108
- );
109
- const pinia = (0, import_pinia.createPinia)();
110
- (0, import_pinia.setActivePinia)(pinia);
111
- return {
112
- copyState: options,
113
- key: "actions",
114
- bind: (state) => {
115
- rawState.name = state.$id;
116
- instancesMap.set(rawState, state);
117
- return rawState;
118
- }
119
- };
120
- })
202
+ /**
203
+ * Bind a store to Pinia
204
+ */
205
+ const bindPinia = (0, coaction.createBinder)({
206
+ handleStore,
207
+ handleState: ((options) => {
208
+ const descriptors = {};
209
+ options.getters = options.getters ?? {};
210
+ options.actions = options.actions ?? {};
211
+ for (const key of Object.keys(options.getters)) {
212
+ const getter = options.getters[key];
213
+ if (typeof getter !== "function") continue;
214
+ descriptors[key] = { get() {
215
+ return getter.call(this, this);
216
+ } };
217
+ }
218
+ const rawState = Object.defineProperties({
219
+ ...options.state?.(),
220
+ ...options.actions
221
+ }, descriptors);
222
+ (0, pinia.setActivePinia)((0, pinia.createPinia)());
223
+ return {
224
+ copyState: options,
225
+ key: "actions",
226
+ bind: (state) => {
227
+ instancesMap.set(rawState, state);
228
+ return rawState;
229
+ }
230
+ };
231
+ })
121
232
  });
122
- var adapt = (store) => store;
123
-
124
- // index.ts
125
- __reExport(index_exports, src_exports, module.exports);
126
- // Annotate the CommonJS export names for ESM import in node:
127
- 0 && (module.exports = {
128
- adapt,
129
- bindPinia
233
+ /**
234
+ * Adapt a store type to Pinia
235
+ */
236
+ const adapt = (store) => store;
237
+ //#endregion
238
+ exports.adapt = adapt;
239
+ exports.bindPinia = bindPinia;
240
+ Object.keys(pinia).forEach(function(k) {
241
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
242
+ enumerable: true,
243
+ get: function() {
244
+ return pinia[k];
245
+ }
246
+ });
130
247
  });
package/dist/index.mjs CHANGED
@@ -1,127 +1,238 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
18
-
19
- // index.ts
20
- var index_exports = {};
21
- __export(index_exports, {
22
- adapt: () => adapt,
23
- bindPinia: () => bindPinia
24
- });
25
-
26
- // src/index.ts
27
- var src_exports = {};
28
- __export(src_exports, {
29
- adapt: () => adapt,
30
- bindPinia: () => bindPinia
31
- });
32
- __reExport(src_exports, pinia_star);
33
1
  import { apply } from "mutability";
34
- import { createBinder } from "coaction";
2
+ import { createBinder, onStoreReady, replaceExternalStoreState, sanitizeInitialStateValue, sanitizeReplacementState } from "coaction";
35
3
  import { createPinia, setActivePinia } from "pinia";
36
- import * as pinia_star from "pinia";
37
- var instancesMap = /* @__PURE__ */ new WeakMap();
38
- var handleStore = (store, state, _, internal) => {
39
- if (!internal.toMutableRaw) {
40
- internal.toMutableRaw = (key) => instancesMap.get(key);
41
- Object.assign(store, {
42
- subscribe: (callback) => {
43
- store._subscriptions.add(callback);
44
- return () => store._subscriptions.delete(callback);
45
- }
46
- });
47
- store._subscriptions = /* @__PURE__ */ new Set();
48
- store._destroyers = /* @__PURE__ */ new Set();
49
- const baseDestroy = store.destroy;
50
- let destroyed = false;
51
- store.destroy = () => {
52
- if (destroyed) {
53
- return;
54
- }
55
- destroyed = true;
56
- baseDestroy();
57
- store._subscriptions.clear();
58
- store._subscriptions = void 0;
59
- store._destroyers.forEach((destroy2) => destroy2());
60
- store._destroyers = void 0;
61
- };
62
- store.apply = (state2 = store.getState(), patches) => {
63
- if (!patches) {
64
- if (state2 === store.getState()) return;
65
- Object.assign(store.getState(), state2);
66
- return;
67
- }
68
- apply(state2, patches);
69
- };
70
- }
71
- const mutableStore = internal.toMutableRaw(state);
72
- if (!mutableStore) {
73
- throw new Error("Pinia store instance is not found");
74
- }
75
- const stopWatch = mutableStore.$subscribe((...args) => {
76
- store._subscriptions.forEach((callback) => callback(...args));
77
- });
78
- const destroy = () => {
79
- instancesMap.delete(state);
80
- stopWatch();
81
- };
82
- store._destroyers.add(destroy);
4
+ export * from "pinia";
5
+ //#endregion
6
+ //#region packages/coaction-pinia/src/index.ts
7
+ const instancesMap = /* @__PURE__ */ new WeakMap();
8
+ const getOwnEnumerableKeys = (value) => Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
9
+ const isUnsafeKey = (key) => typeof key === "string" && (key === "__proto__" || key === "prototype" || key === "constructor");
10
+ const isArrayIndexKey = (key) => {
11
+ if (typeof key !== "string") return false;
12
+ const index = Number(key);
13
+ return Number.isInteger(index) && index >= 0 && index < 2 ** 32 - 1 && String(index) === key;
83
14
  };
84
- var bindPinia = createBinder({
85
- handleStore,
86
- handleState: ((options) => {
87
- const descriptors = {};
88
- options.getters = options.getters ?? {};
89
- for (const key of Object.keys(options.getters)) {
90
- const getter = options.getters[key];
91
- if (typeof getter !== "function") {
92
- continue;
93
- }
94
- descriptors[key] = {
95
- get() {
96
- return getter.call(this, this);
97
- }
98
- };
99
- }
100
- const rawState = Object.defineProperties(
101
- {
102
- ...options.state?.(),
103
- ...options.actions
104
- },
105
- descriptors
106
- );
107
- const pinia = createPinia();
108
- setActivePinia(pinia);
109
- return {
110
- copyState: options,
111
- key: "actions",
112
- bind: (state) => {
113
- rawState.name = state.$id;
114
- instancesMap.set(rawState, state);
115
- return rawState;
116
- }
117
- };
118
- })
119
- });
120
- var adapt = (store) => store;
121
-
122
- // index.ts
123
- __reExport(index_exports, src_exports);
124
- export {
125
- adapt,
126
- bindPinia
15
+ const isObjectRecord = (value) => Object.prototype.toString.call(value) === "[object Object]";
16
+ const replaceMutableState = (rawState, mutableState, publicState, source) => {
17
+ const nextKeys = /* @__PURE__ */ new Set();
18
+ for (const key of getOwnEnumerableKeys(source)) {
19
+ if (isUnsafeKey(key)) continue;
20
+ if (typeof source[key] === "function") continue;
21
+ nextKeys.add(key);
22
+ }
23
+ for (const key of getOwnEnumerableKeys(rawState)) {
24
+ if (isUnsafeKey(key)) {
25
+ delete rawState[key];
26
+ delete mutableState[key];
27
+ delete publicState[key];
28
+ continue;
29
+ }
30
+ if (typeof rawState[key] === "function") continue;
31
+ if (!nextKeys.has(key)) {
32
+ delete rawState[key];
33
+ delete mutableState[key];
34
+ delete publicState[key];
35
+ }
36
+ }
37
+ const rawSeen = /* @__PURE__ */ new WeakMap();
38
+ const mutableSeen = /* @__PURE__ */ new WeakMap();
39
+ const publicSeen = /* @__PURE__ */ new WeakMap();
40
+ rawSeen.set(source, rawState);
41
+ mutableSeen.set(source, mutableState);
42
+ publicSeen.set(source, publicState);
43
+ nextKeys.forEach((key) => {
44
+ rawState[key] = sanitizeReplacementState(source[key], rawSeen);
45
+ mutableState[key] = sanitizeReplacementState(source[key], mutableSeen);
46
+ publicState[key] = sanitizeReplacementState(source[key], publicSeen);
47
+ });
127
48
  };
49
+ const toSnapshot = (value, visited = /* @__PURE__ */ new WeakMap()) => {
50
+ if (Array.isArray(value)) {
51
+ if (visited.has(value)) return visited.get(value);
52
+ const next = [];
53
+ next.length = value.length;
54
+ visited.set(value, next);
55
+ for (let index = 0; index < value.length; index += 1) if (Object.prototype.hasOwnProperty.call(value, index)) next[index] = toSnapshot(value[index], visited);
56
+ const source = value;
57
+ const target = next;
58
+ for (const key of getOwnEnumerableKeys(value)) {
59
+ if (isArrayIndexKey(key) || isUnsafeKey(key)) continue;
60
+ const child = source[key];
61
+ if (typeof child !== "function") target[key] = toSnapshot(child, visited);
62
+ }
63
+ return next;
64
+ }
65
+ if (typeof value === "object" && value !== null) {
66
+ if (!isObjectRecord(value)) return value;
67
+ if (visited.has(value)) return visited.get(value);
68
+ const next = {};
69
+ visited.set(value, next);
70
+ for (const key of getOwnEnumerableKeys(value)) {
71
+ if (isUnsafeKey(key)) continue;
72
+ const child = value[key];
73
+ if (typeof child !== "function") next[key] = toSnapshot(child, visited);
74
+ }
75
+ return next;
76
+ }
77
+ return value;
78
+ };
79
+ const snapshotPureState = (store) => toSnapshot(store.getPureState());
80
+ const isEqualSnapshot = (left, right, visited = /* @__PURE__ */ new WeakMap()) => {
81
+ if (Object.is(left, right)) return true;
82
+ if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
83
+ const leftIsArray = Array.isArray(left);
84
+ const rightIsArray = Array.isArray(right);
85
+ if (leftIsArray || rightIsArray) {
86
+ if (!leftIsArray || !rightIsArray || left.length !== right.length) return false;
87
+ } else if (!isObjectRecord(left) || !isObjectRecord(right)) return false;
88
+ let seenTargets = visited.get(left);
89
+ if (!seenTargets) {
90
+ seenTargets = /* @__PURE__ */ new WeakSet();
91
+ visited.set(left, seenTargets);
92
+ } else if (seenTargets.has(right)) return true;
93
+ seenTargets.add(right);
94
+ const leftRecord = left;
95
+ const rightRecord = right;
96
+ const leftKeys = getOwnEnumerableKeys(left);
97
+ const rightKeys = getOwnEnumerableKeys(right);
98
+ if (leftKeys.length !== rightKeys.length) return false;
99
+ for (const key of leftKeys) {
100
+ if (!Object.prototype.hasOwnProperty.call(rightRecord, key)) return false;
101
+ if (!isEqualSnapshot(leftRecord[key], rightRecord[key], visited)) return false;
102
+ }
103
+ return true;
104
+ };
105
+ const handleStore = (store, state, _, internal) => {
106
+ const rawState = state;
107
+ let isApplyingCoactionState = false;
108
+ let lastSnapshot;
109
+ const restoreClientState = (snapshot) => {
110
+ const mutableStore = internal.toMutableRaw(rawState);
111
+ if (!mutableStore) return;
112
+ isApplyingCoactionState = true;
113
+ try {
114
+ replaceMutableState(internal.rootState ?? rawState, mutableStore, store.getState(), snapshot);
115
+ } finally {
116
+ lastSnapshot = snapshotPureState(store);
117
+ isApplyingCoactionState = false;
118
+ }
119
+ };
120
+ const syncSharedExternalChange = () => {
121
+ const currentSnapshot = snapshotPureState(store);
122
+ if (isApplyingCoactionState) {
123
+ lastSnapshot = currentSnapshot;
124
+ return "handled";
125
+ }
126
+ if (store.share === "client" && lastSnapshot) {
127
+ if (!isEqualSnapshot(currentSnapshot, lastSnapshot)) restoreClientState(lastSnapshot);
128
+ return "ignored";
129
+ }
130
+ if (store.share === "main" && lastSnapshot) {
131
+ const rootState = internal.rootState;
132
+ internal.rootState = lastSnapshot;
133
+ try {
134
+ replaceExternalStoreState(store, internal, currentSnapshot, { syncImmutable: false });
135
+ } finally {
136
+ internal.rootState = rootState;
137
+ }
138
+ lastSnapshot = currentSnapshot;
139
+ return "handled";
140
+ }
141
+ lastSnapshot = currentSnapshot;
142
+ return "external";
143
+ };
144
+ if (!internal.toMutableRaw) {
145
+ internal.toMutableRaw = (key) => instancesMap.get(key);
146
+ Object.assign(store, { subscribe: (callback) => {
147
+ store._subscriptions.add(callback);
148
+ return () => {
149
+ store._subscriptions?.delete(callback);
150
+ };
151
+ } });
152
+ store._subscriptions = /* @__PURE__ */ new Set();
153
+ store._destroyers = /* @__PURE__ */ new Set();
154
+ const baseDestroy = store.destroy;
155
+ let destroyed = false;
156
+ store.destroy = () => {
157
+ if (destroyed) return;
158
+ destroyed = true;
159
+ store._subscriptions?.clear();
160
+ store._subscriptions = void 0;
161
+ store._destroyers?.forEach((destroy) => destroy());
162
+ store._destroyers?.clear();
163
+ store._destroyers = void 0;
164
+ baseDestroy();
165
+ };
166
+ store.apply = (nextState = store.getState(), patches) => {
167
+ isApplyingCoactionState = true;
168
+ try {
169
+ if (!patches) {
170
+ if (nextState === store.getState()) return;
171
+ replaceMutableState(internal.rootState ?? rawState, internal.toMutableRaw(rawState), store.getState(), nextState);
172
+ return;
173
+ }
174
+ apply(nextState, patches);
175
+ } finally {
176
+ lastSnapshot = snapshotPureState(store);
177
+ isApplyingCoactionState = false;
178
+ internal.notifyStateChange?.();
179
+ }
180
+ };
181
+ }
182
+ const mutableStore = internal.toMutableRaw(state);
183
+ if (!mutableStore) throw new Error("Pinia store instance is not found");
184
+ let stopWatch;
185
+ const cancelReadySubscription = onStoreReady(store, () => {
186
+ replaceMutableState(internal.rootState ?? rawState, mutableStore, store.getState(), sanitizeInitialStateValue(snapshotPureState(store)));
187
+ lastSnapshot = snapshotPureState(store);
188
+ stopWatch = mutableStore.$subscribe((...args) => {
189
+ const change = syncSharedExternalChange();
190
+ if (change === "ignored") return;
191
+ if (change === "external") internal.notifyStateChange?.();
192
+ store._subscriptions.forEach((callback) => callback(...args));
193
+ });
194
+ });
195
+ const destroy = () => {
196
+ cancelReadySubscription();
197
+ instancesMap.delete(state);
198
+ stopWatch?.();
199
+ };
200
+ store._destroyers.add(destroy);
201
+ };
202
+ /**
203
+ * Bind a store to Pinia
204
+ */
205
+ const bindPinia = createBinder({
206
+ handleStore,
207
+ handleState: ((options) => {
208
+ const descriptors = {};
209
+ options.getters = options.getters ?? {};
210
+ options.actions = options.actions ?? {};
211
+ for (const key of Object.keys(options.getters)) {
212
+ const getter = options.getters[key];
213
+ if (typeof getter !== "function") continue;
214
+ descriptors[key] = { get() {
215
+ return getter.call(this, this);
216
+ } };
217
+ }
218
+ const rawState = Object.defineProperties({
219
+ ...options.state?.(),
220
+ ...options.actions
221
+ }, descriptors);
222
+ setActivePinia(createPinia());
223
+ return {
224
+ copyState: options,
225
+ key: "actions",
226
+ bind: (state) => {
227
+ instancesMap.set(rawState, state);
228
+ return rawState;
229
+ }
230
+ };
231
+ })
232
+ });
233
+ /**
234
+ * Adapt a store type to Pinia
235
+ */
236
+ const adapt = (store) => store;
237
+ //#endregion
238
+ export { adapt, bindPinia };
package/package.json CHANGED
@@ -1,19 +1,30 @@
1
1
  {
2
2
  "name": "@coaction/pinia",
3
- "version": "1.5.0",
3
+ "version": "2.0.0",
4
4
  "description": "A Coaction integration tool for Pinia",
5
5
  "keywords": [
6
- "state",
7
6
  "coaction",
8
- "pinia"
7
+ "pinia",
8
+ "state"
9
9
  ],
10
- "authors": [
11
- "Michael Lin <unadlib@gmail.com> (https://github.com/unadlib)"
12
- ],
13
- "homepage": "https://github.com/unadlib/coaction/tree/main/packages/coaction-pinia#readme",
10
+ "homepage": "https://github.com/coactionjs/coaction/tree/main/packages/coaction-pinia#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/coactionjs/coaction/issues"
13
+ },
14
14
  "license": "MIT",
15
+ "author": "unadlib",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/coactionjs/coaction.git",
19
+ "directory": "packages/coaction-pinia"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "sideEffects": false,
15
25
  "main": "dist/index.js",
16
26
  "module": "dist/index.mjs",
27
+ "types": "dist/index.d.ts",
17
28
  "exports": {
18
29
  ".": {
19
30
  "types": "./dist/index.d.ts",
@@ -23,53 +34,30 @@
23
34
  },
24
35
  "./package.json": "./package.json"
25
36
  },
26
- "types": "dist/index.d.ts",
27
- "sideEffects": false,
28
- "files": [
29
- "dist"
30
- ],
31
- "repository": {
32
- "type": "git",
33
- "url": "https://github.com/unadlib/coaction.git",
34
- "directory": "packages/coaction-pinia"
35
- },
36
- "bugs": {
37
- "url": "https://github.com/unadlib/coaction/issues"
38
- },
39
- "peerDependencies": {
40
- "coaction": "^1.5.0",
41
- "mutative": "^1.1.0",
42
- "pinia": "^2.0 || ^3.0.0"
37
+ "publishConfig": {
38
+ "access": "public",
39
+ "provenance": true
43
40
  },
44
- "peerDependenciesMeta": {
45
- "coaction": {
46
- "optional": true
47
- },
48
- "mutative": {
49
- "optional": true
50
- },
51
- "pinia": {
52
- "optional": true
53
- }
41
+ "dependencies": {
42
+ "mutability": "^1.2.1"
54
43
  },
55
44
  "devDependencies": {
56
45
  "data-transport": "^5.0.3",
57
46
  "mutative": "^1.3.0",
58
47
  "pinia": "^3.0.4",
59
- "coaction": "1.5.0"
48
+ "coaction": "2.0.0"
60
49
  },
61
- "dependencies": {
62
- "mutability": "^1.2.1"
63
- },
64
- "publishConfig": {
65
- "access": "public",
66
- "provenance": true
50
+ "peerDependencies": {
51
+ "coaction": "^2.0.0",
52
+ "pinia": "^2.0 || ^3.0.0"
67
53
  },
68
- "author": "unadlib",
54
+ "authors": [
55
+ "Michael Lin <unadlib@gmail.com> (https://github.com/unadlib)"
56
+ ],
69
57
  "scripts": {
70
58
  "clean": "rm -rf dist",
71
59
  "test": "vitest run test",
72
- "build": "tsup index.ts --format cjs,esm --dts --clean --out-dir dist",
73
- "dev": "tsup index.ts --format cjs,esm --dts --watch --out-dir dist"
60
+ "build": "node ../../scripts/build-package.mjs",
61
+ "dev": "node ../../scripts/build-package.mjs --watch"
74
62
  }
75
63
  }