pixel-data-js 0.0.1 → 0.0.2

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.
@@ -20,144 +20,44 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
- createPiniaSimplePersist: () => createPiniaSimplePersist,
24
- makeSimplePersistMapper: () => makeSimplePersistMapper
23
+ deserializeImageData: () => deserializeImageData,
24
+ deserializeNullableImageData: () => deserializeNullableImageData,
25
+ serializeImageData: () => serializeImageData,
26
+ serializeNullableImageData: () => serializeNullableImageData
25
27
  });
26
28
  module.exports = __toCommonJS(src_exports);
27
29
 
28
- // src/plugin.ts
29
- var import_pinia = require("pinia");
30
- function createPiniaSimplePersist(globalOptions = {}) {
31
- const makeKey = globalOptions.makeKey ?? ((id) => `pinia-${id}`);
32
- return (context) => {
33
- const { store, options } = context;
34
- ensureStoreHasRestoreState(store);
35
- ensureStoreHasSerializeState(store);
36
- const persist = options.persist;
37
- if (!persist) return;
38
- const {
39
- key = makeKey(store.$id),
40
- storage = localStorage,
41
- serializer = {
42
- serialize: JSON.stringify,
43
- deserialize: JSON.parse
44
- },
45
- debounce = 0,
46
- beforeRestore,
47
- afterRestore,
48
- onRestoreError
49
- } = { ...globalOptions, ...persist };
50
- const restoreState = () => {
51
- beforeRestore?.(context);
52
- const stored = storage.getItem(key);
53
- if (!stored) return;
54
- try {
55
- const data = serializer.deserialize(stored);
56
- store.$restoreState(data);
57
- afterRestore?.(context);
58
- } catch (error) {
59
- if (onRestoreError) {
60
- onRestoreError(error instanceof Error ? error : new Error(String(error)));
61
- } else {
62
- throw error;
63
- }
64
- }
65
- };
66
- const saveState = () => {
67
- const state = store.$serializeState();
68
- const serialized = serializer.serialize(state);
69
- storage.setItem(key, serialized);
70
- };
71
- let finalSave = saveState;
72
- let cleanupDebounce;
73
- if (debounce) {
74
- const { debouncedFn, cleanup } = makeDebounce(saveState, debounce);
75
- finalSave = debouncedFn;
76
- cleanupDebounce = cleanup;
77
- }
78
- const unsubscribe = store.$subscribe(() => {
79
- finalSave();
80
- }, { detached: true });
81
- const originalDispose = store.$dispose;
82
- store.$dispose = function() {
83
- unsubscribe();
84
- cleanupDebounce?.();
85
- originalDispose.call(this);
86
- };
87
- restoreState();
30
+ // src/ImageData/serialization.ts
31
+ function serializeImageData(imageData) {
32
+ const binary = String.fromCharCode(...new Uint8Array(imageData.data.buffer));
33
+ const base64 = btoa(binary);
34
+ return {
35
+ width: imageData.width,
36
+ height: imageData.height,
37
+ data: base64
88
38
  };
89
39
  }
90
- var makeDebounce = (callback, waitFor) => {
91
- let timeout;
92
- const debouncedFn = () => {
93
- if (timeout) clearTimeout(timeout);
94
- timeout = setTimeout(() => {
95
- callback();
96
- }, waitFor);
97
- };
98
- const cleanup = () => {
99
- if (timeout) {
100
- clearTimeout(timeout);
101
- timeout = void 0;
102
- }
103
- };
104
- return { debouncedFn, cleanup };
105
- };
106
- function ensureStoreHasRestoreState(store) {
107
- if (typeof store.$restoreState !== "function") {
108
- throw new Error("A store using pinia-simple-persist must have a $restoreState() method");
109
- }
40
+ function serializeNullableImageData(imageData) {
41
+ if (!imageData) return null;
42
+ return serializeImageData(imageData);
110
43
  }
111
- function ensureStoreHasSerializeState(store) {
112
- if (typeof store.$serializeState !== "function") {
113
- throw new Error("A store using pinia-simple-persist must have a $serializeState() method");
44
+ function deserializeImageData(serialized) {
45
+ const binary = atob(serialized.data);
46
+ const bytes = new Uint8ClampedArray(binary.length);
47
+ for (let i = 0; i < binary.length; i++) {
48
+ bytes[i] = binary.charCodeAt(i);
114
49
  }
50
+ return new ImageData(bytes, serialized.width, serialized.height);
115
51
  }
116
-
117
- // src/mapper.ts
118
- var import_vue = require("vue");
119
- function makeSimplePersistMapper(state, defaults) {
120
- return {
121
- $serializeState() {
122
- const out = {};
123
- for (const key in state) {
124
- const item = state[key];
125
- let value;
126
- if ((0, import_vue.isRef)(item)) {
127
- value = item.value;
128
- } else {
129
- value = item;
130
- }
131
- out[key] = (0, import_vue.isReactive)(value) ? (0, import_vue.toRaw)(value) : value;
132
- }
133
- return out;
134
- },
135
- $restoreState(data) {
136
- for (const key in state) {
137
- if (!(key in data)) continue;
138
- const item = state[key];
139
- if ((0, import_vue.isRef)(item)) {
140
- item.value = data[key];
141
- } else if ((0, import_vue.isReactive)(item)) {
142
- Object.assign(item, data[key]);
143
- }
144
- }
145
- },
146
- $reset() {
147
- for (const key in state) {
148
- const item = state[key];
149
- if ((0, import_vue.isRef)(item)) {
150
- item.value = defaults[key];
151
- } else if ((0, import_vue.isReactive)(item)) {
152
- Object.assign(item, defaults[key]);
153
- }
154
- }
155
- }
156
- };
52
+ function deserializeNullableImageData(serialized) {
53
+ if (!serialized) return null;
54
+ return deserializeImageData(serialized);
157
55
  }
158
56
  // Annotate the CommonJS export names for ESM import in node:
159
57
  0 && (module.exports = {
160
- createPiniaSimplePersist,
161
- makeSimplePersistMapper
58
+ deserializeImageData,
59
+ deserializeNullableImageData,
60
+ serializeImageData,
61
+ serializeNullableImageData
162
62
  });
163
63
  //# sourceMappingURL=index.dev.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/plugin.ts","../src/mapper.ts"],"sourcesContent":["export * from './plugin'\nexport { makeSimplePersistMapper } from './mapper'\n","import type { PiniaPluginContext } from 'pinia'\nimport 'pinia'\nimport type { Serializer, StorageLike } from './types'\n\nexport type BaseSimplePersistOptions<Serialized> = {\n storage?: StorageLike\n serializer?: Serializer<Serialized>,\n debounce?: number\n beforeRestore?: (context: PiniaPluginContext) => void\n afterRestore?: (context: PiniaPluginContext) => void,\n onRestoreError?: (err: Error) => void,\n}\n\nexport type GlobalSimplePersistOptions = BaseSimplePersistOptions<any> & {\n makeKey?: (storeId: string) => string,\n}\n\nexport type SimplePersistOptions<Serialized> = BaseSimplePersistOptions<Serialized> & {\n key?: string,\n}\n\nexport function createPiniaSimplePersist(globalOptions: GlobalSimplePersistOptions = {}) {\n const makeKey = globalOptions.makeKey ?? ((id: string) => `pinia-${id}`)\n\n return (context: PiniaPluginContext) => {\n const { store, options } = context\n\n ensureStoreHasRestoreState(store)\n ensureStoreHasSerializeState(store)\n\n const persist = options.persist as SimplePersistOptions<any> | undefined\n if (!persist) return\n\n const {\n key = makeKey(store.$id),\n storage = localStorage,\n serializer = {\n serialize: JSON.stringify,\n deserialize: JSON.parse,\n },\n debounce = 0,\n beforeRestore,\n afterRestore,\n onRestoreError,\n } = { ...globalOptions, ...persist }\n\n const restoreState = () => {\n beforeRestore?.(context)\n\n const stored = storage.getItem(key)\n if (!stored) return\n\n try {\n const data = serializer.deserialize(stored)\n store.$restoreState(data)\n afterRestore?.(context)\n } catch (error) {\n if (onRestoreError) {\n onRestoreError(error instanceof Error ? error : new Error(String(error)))\n } else {\n throw error\n }\n }\n }\n\n const saveState = () => {\n const state = store.$serializeState()\n const serialized = serializer.serialize(state)\n storage.setItem(key, serialized)\n }\n\n let finalSave = saveState\n let cleanupDebounce: (() => void) | undefined\n\n if (debounce) {\n const { debouncedFn, cleanup } = makeDebounce(saveState, debounce)\n finalSave = debouncedFn\n cleanupDebounce = cleanup\n }\n\n // Watch for changes and persist\n const unsubscribe = store.$subscribe(() => {\n finalSave()\n }, { detached: true })\n\n // Cleanup on store disposal\n const originalDispose = store.$dispose\n store.$dispose = function() {\n unsubscribe()\n cleanupDebounce?.()\n originalDispose.call(this)\n }\n\n // Restore state on initialization\n restoreState()\n }\n}\n\nconst makeDebounce = <T extends () => void>(\n callback: T,\n waitFor: number,\n) => {\n let timeout: ReturnType<typeof setTimeout> | undefined\n\n const debouncedFn = (): void => {\n if (timeout) clearTimeout(timeout)\n timeout = setTimeout(() => {\n callback()\n }, waitFor)\n }\n\n const cleanup = (): void => {\n if (timeout) {\n clearTimeout(timeout)\n timeout = undefined\n }\n }\n\n return { debouncedFn, cleanup }\n}\n\nfunction ensureStoreHasRestoreState<T>(store: T): asserts store is T & { $restoreState: (data: any) => void } {\n if (typeof (store as any).$restoreState !== 'function') {\n throw new Error('A store using pinia-simple-persist must have a $restoreState() method')\n }\n}\n\nfunction ensureStoreHasSerializeState<T>(store: T): asserts store is T & { $serializeState: () => any } {\n if (typeof (store as any).$serializeState !== 'function') {\n throw new Error('A store using pinia-simple-persist must have a $serializeState() method')\n }\n}\n","import type { Ref } from 'vue'\nimport { toRaw, isRef, isReactive } from 'vue'\n\ntype RefOrReactive<T> = Ref<T> | T\n\nexport function makeSimplePersistMapper<T extends Record<string, any>>(\n state: { [K in keyof T]: RefOrReactive<T[K]> },\n defaults: T,\n) {\n return {\n $serializeState(): T {\n const out = {} as T\n for (const key in state) {\n const item = state[key]\n let value: any\n\n if (isRef(item)) {\n value = item.value\n } else {\n value = item\n }\n\n out[key] = isReactive(value) ? toRaw(value) : value\n }\n return out\n },\n\n $restoreState(data: T) {\n for (const key in state) {\n if (!(key in data)) continue\n\n const item = state[key]\n\n if (isRef(item)) {\n item.value = data[key]\n } else if (isReactive(item)) {\n Object.assign(item, data[key])\n }\n }\n },\n\n $reset() {\n for (const key in state) {\n const item = state[key]\n\n if (isRef(item)) {\n item.value = defaults[key]\n } else if (isReactive(item)) {\n Object.assign(item, defaults[key])\n }\n }\n },\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/ImageData/serialization.ts"],"sourcesContent":["export * from './ImageData/serialization'\n","export type SerializedImageData = {\n width: number,\n height: number,\n data: string,\n}\n\n/**\n * Serialize for use in JSON. Stored as base64 encoded string.\n */\nexport function serializeImageData<T extends ImageData>(imageData: T): SerializedImageData {\n const binary = String.fromCharCode(...new Uint8Array(imageData.data.buffer))\n const base64 = btoa(binary)\n\n return {\n width: imageData.width,\n height: imageData.height,\n data: base64,\n }\n}\n\nexport function serializeNullableImageData<T extends ImageData | null>(imageData: T): T extends null ? null : SerializedImageData {\n if (!imageData) return null as any\n\n return serializeImageData(imageData) as any\n}\n\nexport function deserializeImageData<T extends SerializedImageData>(serialized: T): ImageData {\n const binary = atob(serialized.data as string)\n const bytes = new Uint8ClampedArray(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n\n return new ImageData(bytes, serialized.width, serialized.height) as any\n}\n\nexport function deserializeNullableImageData<T extends SerializedImageData | null>(serialized: T): T extends null ? null : ImageData {\n if (!serialized) return null as any\n return deserializeImageData(serialized) as any\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACSO,SAAS,mBAAwC,WAAmC;AACzF,QAAM,SAAS,OAAO,aAAa,GAAG,IAAI,WAAW,UAAU,KAAK,MAAM,CAAC;AAC3E,QAAM,SAAS,KAAK,MAAM;AAE1B,SAAO;AAAA,IACL,OAAO,UAAU;AAAA,IACjB,QAAQ,UAAU;AAAA,IAClB,MAAM;AAAA,EACR;AACF;AAEO,SAAS,2BAAuD,WAA2D;AAChI,MAAI,CAAC,UAAW,QAAO;AAEvB,SAAO,mBAAmB,SAAS;AACrC;AAEO,SAAS,qBAAoD,YAA0B;AAC5F,QAAM,SAAS,KAAK,WAAW,IAAc;AAC7C,QAAM,QAAQ,IAAI,kBAAkB,OAAO,MAAM;AACjD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AAEA,SAAO,IAAI,UAAU,OAAO,WAAW,OAAO,WAAW,MAAM;AACjE;AAEO,SAAS,6BAAmE,YAAkD;AACnI,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,qBAAqB,UAAU;AACxC;","names":[]}
package/dist/index.dev.js CHANGED
@@ -1,135 +1,33 @@
1
- // src/plugin.ts
2
- import "pinia";
3
- function createPiniaSimplePersist(globalOptions = {}) {
4
- const makeKey = globalOptions.makeKey ?? ((id) => `pinia-${id}`);
5
- return (context) => {
6
- const { store, options } = context;
7
- ensureStoreHasRestoreState(store);
8
- ensureStoreHasSerializeState(store);
9
- const persist = options.persist;
10
- if (!persist) return;
11
- const {
12
- key = makeKey(store.$id),
13
- storage = localStorage,
14
- serializer = {
15
- serialize: JSON.stringify,
16
- deserialize: JSON.parse
17
- },
18
- debounce = 0,
19
- beforeRestore,
20
- afterRestore,
21
- onRestoreError
22
- } = { ...globalOptions, ...persist };
23
- const restoreState = () => {
24
- beforeRestore?.(context);
25
- const stored = storage.getItem(key);
26
- if (!stored) return;
27
- try {
28
- const data = serializer.deserialize(stored);
29
- store.$restoreState(data);
30
- afterRestore?.(context);
31
- } catch (error) {
32
- if (onRestoreError) {
33
- onRestoreError(error instanceof Error ? error : new Error(String(error)));
34
- } else {
35
- throw error;
36
- }
37
- }
38
- };
39
- const saveState = () => {
40
- const state = store.$serializeState();
41
- const serialized = serializer.serialize(state);
42
- storage.setItem(key, serialized);
43
- };
44
- let finalSave = saveState;
45
- let cleanupDebounce;
46
- if (debounce) {
47
- const { debouncedFn, cleanup } = makeDebounce(saveState, debounce);
48
- finalSave = debouncedFn;
49
- cleanupDebounce = cleanup;
50
- }
51
- const unsubscribe = store.$subscribe(() => {
52
- finalSave();
53
- }, { detached: true });
54
- const originalDispose = store.$dispose;
55
- store.$dispose = function() {
56
- unsubscribe();
57
- cleanupDebounce?.();
58
- originalDispose.call(this);
59
- };
60
- restoreState();
1
+ // src/ImageData/serialization.ts
2
+ function serializeImageData(imageData) {
3
+ const binary = String.fromCharCode(...new Uint8Array(imageData.data.buffer));
4
+ const base64 = btoa(binary);
5
+ return {
6
+ width: imageData.width,
7
+ height: imageData.height,
8
+ data: base64
61
9
  };
62
10
  }
63
- var makeDebounce = (callback, waitFor) => {
64
- let timeout;
65
- const debouncedFn = () => {
66
- if (timeout) clearTimeout(timeout);
67
- timeout = setTimeout(() => {
68
- callback();
69
- }, waitFor);
70
- };
71
- const cleanup = () => {
72
- if (timeout) {
73
- clearTimeout(timeout);
74
- timeout = void 0;
75
- }
76
- };
77
- return { debouncedFn, cleanup };
78
- };
79
- function ensureStoreHasRestoreState(store) {
80
- if (typeof store.$restoreState !== "function") {
81
- throw new Error("A store using pinia-simple-persist must have a $restoreState() method");
82
- }
11
+ function serializeNullableImageData(imageData) {
12
+ if (!imageData) return null;
13
+ return serializeImageData(imageData);
83
14
  }
84
- function ensureStoreHasSerializeState(store) {
85
- if (typeof store.$serializeState !== "function") {
86
- throw new Error("A store using pinia-simple-persist must have a $serializeState() method");
15
+ function deserializeImageData(serialized) {
16
+ const binary = atob(serialized.data);
17
+ const bytes = new Uint8ClampedArray(binary.length);
18
+ for (let i = 0; i < binary.length; i++) {
19
+ bytes[i] = binary.charCodeAt(i);
87
20
  }
21
+ return new ImageData(bytes, serialized.width, serialized.height);
88
22
  }
89
-
90
- // src/mapper.ts
91
- import { toRaw, isRef, isReactive } from "vue";
92
- function makeSimplePersistMapper(state, defaults) {
93
- return {
94
- $serializeState() {
95
- const out = {};
96
- for (const key in state) {
97
- const item = state[key];
98
- let value;
99
- if (isRef(item)) {
100
- value = item.value;
101
- } else {
102
- value = item;
103
- }
104
- out[key] = isReactive(value) ? toRaw(value) : value;
105
- }
106
- return out;
107
- },
108
- $restoreState(data) {
109
- for (const key in state) {
110
- if (!(key in data)) continue;
111
- const item = state[key];
112
- if (isRef(item)) {
113
- item.value = data[key];
114
- } else if (isReactive(item)) {
115
- Object.assign(item, data[key]);
116
- }
117
- }
118
- },
119
- $reset() {
120
- for (const key in state) {
121
- const item = state[key];
122
- if (isRef(item)) {
123
- item.value = defaults[key];
124
- } else if (isReactive(item)) {
125
- Object.assign(item, defaults[key]);
126
- }
127
- }
128
- }
129
- };
23
+ function deserializeNullableImageData(serialized) {
24
+ if (!serialized) return null;
25
+ return deserializeImageData(serialized);
130
26
  }
131
27
  export {
132
- createPiniaSimplePersist,
133
- makeSimplePersistMapper
28
+ deserializeImageData,
29
+ deserializeNullableImageData,
30
+ serializeImageData,
31
+ serializeNullableImageData
134
32
  };
135
33
  //# sourceMappingURL=index.dev.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugin.ts","../src/mapper.ts"],"sourcesContent":["import type { PiniaPluginContext } from 'pinia'\nimport 'pinia'\nimport type { Serializer, StorageLike } from './types'\n\nexport type BaseSimplePersistOptions<Serialized> = {\n storage?: StorageLike\n serializer?: Serializer<Serialized>,\n debounce?: number\n beforeRestore?: (context: PiniaPluginContext) => void\n afterRestore?: (context: PiniaPluginContext) => void,\n onRestoreError?: (err: Error) => void,\n}\n\nexport type GlobalSimplePersistOptions = BaseSimplePersistOptions<any> & {\n makeKey?: (storeId: string) => string,\n}\n\nexport type SimplePersistOptions<Serialized> = BaseSimplePersistOptions<Serialized> & {\n key?: string,\n}\n\nexport function createPiniaSimplePersist(globalOptions: GlobalSimplePersistOptions = {}) {\n const makeKey = globalOptions.makeKey ?? ((id: string) => `pinia-${id}`)\n\n return (context: PiniaPluginContext) => {\n const { store, options } = context\n\n ensureStoreHasRestoreState(store)\n ensureStoreHasSerializeState(store)\n\n const persist = options.persist as SimplePersistOptions<any> | undefined\n if (!persist) return\n\n const {\n key = makeKey(store.$id),\n storage = localStorage,\n serializer = {\n serialize: JSON.stringify,\n deserialize: JSON.parse,\n },\n debounce = 0,\n beforeRestore,\n afterRestore,\n onRestoreError,\n } = { ...globalOptions, ...persist }\n\n const restoreState = () => {\n beforeRestore?.(context)\n\n const stored = storage.getItem(key)\n if (!stored) return\n\n try {\n const data = serializer.deserialize(stored)\n store.$restoreState(data)\n afterRestore?.(context)\n } catch (error) {\n if (onRestoreError) {\n onRestoreError(error instanceof Error ? error : new Error(String(error)))\n } else {\n throw error\n }\n }\n }\n\n const saveState = () => {\n const state = store.$serializeState()\n const serialized = serializer.serialize(state)\n storage.setItem(key, serialized)\n }\n\n let finalSave = saveState\n let cleanupDebounce: (() => void) | undefined\n\n if (debounce) {\n const { debouncedFn, cleanup } = makeDebounce(saveState, debounce)\n finalSave = debouncedFn\n cleanupDebounce = cleanup\n }\n\n // Watch for changes and persist\n const unsubscribe = store.$subscribe(() => {\n finalSave()\n }, { detached: true })\n\n // Cleanup on store disposal\n const originalDispose = store.$dispose\n store.$dispose = function() {\n unsubscribe()\n cleanupDebounce?.()\n originalDispose.call(this)\n }\n\n // Restore state on initialization\n restoreState()\n }\n}\n\nconst makeDebounce = <T extends () => void>(\n callback: T,\n waitFor: number,\n) => {\n let timeout: ReturnType<typeof setTimeout> | undefined\n\n const debouncedFn = (): void => {\n if (timeout) clearTimeout(timeout)\n timeout = setTimeout(() => {\n callback()\n }, waitFor)\n }\n\n const cleanup = (): void => {\n if (timeout) {\n clearTimeout(timeout)\n timeout = undefined\n }\n }\n\n return { debouncedFn, cleanup }\n}\n\nfunction ensureStoreHasRestoreState<T>(store: T): asserts store is T & { $restoreState: (data: any) => void } {\n if (typeof (store as any).$restoreState !== 'function') {\n throw new Error('A store using pinia-simple-persist must have a $restoreState() method')\n }\n}\n\nfunction ensureStoreHasSerializeState<T>(store: T): asserts store is T & { $serializeState: () => any } {\n if (typeof (store as any).$serializeState !== 'function') {\n throw new Error('A store using pinia-simple-persist must have a $serializeState() method')\n }\n}\n","import type { Ref } from 'vue'\nimport { toRaw, isRef, isReactive } from 'vue'\n\ntype RefOrReactive<T> = Ref<T> | T\n\nexport function makeSimplePersistMapper<T extends Record<string, any>>(\n state: { [K in keyof T]: RefOrReactive<T[K]> },\n defaults: T,\n) {\n return {\n $serializeState(): T {\n const out = {} as T\n for (const key in state) {\n const item = state[key]\n let value: any\n\n if (isRef(item)) {\n value = item.value\n } else {\n value = item\n }\n\n out[key] = isReactive(value) ? toRaw(value) : value\n }\n return out\n },\n\n $restoreState(data: T) {\n for (const key in state) {\n if (!(key in data)) continue\n\n const item = state[key]\n\n if (isRef(item)) {\n item.value = data[key]\n } else if (isReactive(item)) {\n Object.assign(item, data[key])\n }\n }\n },\n\n $reset() {\n for (const key in state) {\n const item = state[key]\n\n if (isRef(item)) {\n item.value = defaults[key]\n } else if (isReactive(item)) {\n Object.assign(item, defaults[key])\n }\n }\n },\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/ImageData/serialization.ts"],"sourcesContent":["export type SerializedImageData = {\n width: number,\n height: number,\n data: string,\n}\n\n/**\n * Serialize for use in JSON. Stored as base64 encoded string.\n */\nexport function serializeImageData<T extends ImageData>(imageData: T): SerializedImageData {\n const binary = String.fromCharCode(...new Uint8Array(imageData.data.buffer))\n const base64 = btoa(binary)\n\n return {\n width: imageData.width,\n height: imageData.height,\n data: base64,\n }\n}\n\nexport function serializeNullableImageData<T extends ImageData | null>(imageData: T): T extends null ? null : SerializedImageData {\n if (!imageData) return null as any\n\n return serializeImageData(imageData) as any\n}\n\nexport function deserializeImageData<T extends SerializedImageData>(serialized: T): ImageData {\n const binary = atob(serialized.data as string)\n const bytes = new Uint8ClampedArray(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n\n return new ImageData(bytes, serialized.width, serialized.height) as any\n}\n\nexport function deserializeNullableImageData<T extends SerializedImageData | null>(serialized: T): T extends null ? null : ImageData {\n if (!serialized) return null as any\n return deserializeImageData(serialized) as any\n}\n"],"mappings":";AASO,SAAS,mBAAwC,WAAmC;AACzF,QAAM,SAAS,OAAO,aAAa,GAAG,IAAI,WAAW,UAAU,KAAK,MAAM,CAAC;AAC3E,QAAM,SAAS,KAAK,MAAM;AAE1B,SAAO;AAAA,IACL,OAAO,UAAU;AAAA,IACjB,QAAQ,UAAU;AAAA,IAClB,MAAM;AAAA,EACR;AACF;AAEO,SAAS,2BAAuD,WAA2D;AAChI,MAAI,CAAC,UAAW,QAAO;AAEvB,SAAO,mBAAmB,SAAS;AACrC;AAEO,SAAS,qBAAoD,YAA0B;AAC5F,QAAM,SAAS,KAAK,WAAW,IAAc;AAC7C,QAAM,QAAQ,IAAI,kBAAkB,OAAO,MAAM;AACjD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AAEA,SAAO,IAAI,UAAU,OAAO,WAAW,OAAO,WAAW,MAAM;AACjE;AAEO,SAAS,6BAAmE,YAAkD;AACnI,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,qBAAqB,UAAU;AACxC;","names":[]}
@@ -20,144 +20,44 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
- createPiniaSimplePersist: () => createPiniaSimplePersist,
24
- makeSimplePersistMapper: () => makeSimplePersistMapper
23
+ deserializeImageData: () => deserializeImageData,
24
+ deserializeNullableImageData: () => deserializeNullableImageData,
25
+ serializeImageData: () => serializeImageData,
26
+ serializeNullableImageData: () => serializeNullableImageData
25
27
  });
26
28
  module.exports = __toCommonJS(src_exports);
27
29
 
28
- // src/plugin.ts
29
- var import_pinia = require("pinia");
30
- function createPiniaSimplePersist(globalOptions = {}) {
31
- const makeKey = globalOptions.makeKey ?? ((id) => `pinia-${id}`);
32
- return (context) => {
33
- const { store, options } = context;
34
- ensureStoreHasRestoreState(store);
35
- ensureStoreHasSerializeState(store);
36
- const persist = options.persist;
37
- if (!persist) return;
38
- const {
39
- key = makeKey(store.$id),
40
- storage = localStorage,
41
- serializer = {
42
- serialize: JSON.stringify,
43
- deserialize: JSON.parse
44
- },
45
- debounce = 0,
46
- beforeRestore,
47
- afterRestore,
48
- onRestoreError
49
- } = { ...globalOptions, ...persist };
50
- const restoreState = () => {
51
- beforeRestore?.(context);
52
- const stored = storage.getItem(key);
53
- if (!stored) return;
54
- try {
55
- const data = serializer.deserialize(stored);
56
- store.$restoreState(data);
57
- afterRestore?.(context);
58
- } catch (error) {
59
- if (onRestoreError) {
60
- onRestoreError(error instanceof Error ? error : new Error(String(error)));
61
- } else {
62
- throw error;
63
- }
64
- }
65
- };
66
- const saveState = () => {
67
- const state = store.$serializeState();
68
- const serialized = serializer.serialize(state);
69
- storage.setItem(key, serialized);
70
- };
71
- let finalSave = saveState;
72
- let cleanupDebounce;
73
- if (debounce) {
74
- const { debouncedFn, cleanup } = makeDebounce(saveState, debounce);
75
- finalSave = debouncedFn;
76
- cleanupDebounce = cleanup;
77
- }
78
- const unsubscribe = store.$subscribe(() => {
79
- finalSave();
80
- }, { detached: true });
81
- const originalDispose = store.$dispose;
82
- store.$dispose = function() {
83
- unsubscribe();
84
- cleanupDebounce?.();
85
- originalDispose.call(this);
86
- };
87
- restoreState();
30
+ // src/ImageData/serialization.ts
31
+ function serializeImageData(imageData) {
32
+ const binary = String.fromCharCode(...new Uint8Array(imageData.data.buffer));
33
+ const base64 = btoa(binary);
34
+ return {
35
+ width: imageData.width,
36
+ height: imageData.height,
37
+ data: base64
88
38
  };
89
39
  }
90
- var makeDebounce = (callback, waitFor) => {
91
- let timeout;
92
- const debouncedFn = () => {
93
- if (timeout) clearTimeout(timeout);
94
- timeout = setTimeout(() => {
95
- callback();
96
- }, waitFor);
97
- };
98
- const cleanup = () => {
99
- if (timeout) {
100
- clearTimeout(timeout);
101
- timeout = void 0;
102
- }
103
- };
104
- return { debouncedFn, cleanup };
105
- };
106
- function ensureStoreHasRestoreState(store) {
107
- if (typeof store.$restoreState !== "function") {
108
- throw new Error("A store using pinia-simple-persist must have a $restoreState() method");
109
- }
40
+ function serializeNullableImageData(imageData) {
41
+ if (!imageData) return null;
42
+ return serializeImageData(imageData);
110
43
  }
111
- function ensureStoreHasSerializeState(store) {
112
- if (typeof store.$serializeState !== "function") {
113
- throw new Error("A store using pinia-simple-persist must have a $serializeState() method");
44
+ function deserializeImageData(serialized) {
45
+ const binary = atob(serialized.data);
46
+ const bytes = new Uint8ClampedArray(binary.length);
47
+ for (let i = 0; i < binary.length; i++) {
48
+ bytes[i] = binary.charCodeAt(i);
114
49
  }
50
+ return new ImageData(bytes, serialized.width, serialized.height);
115
51
  }
116
-
117
- // src/mapper.ts
118
- var import_vue = require("vue");
119
- function makeSimplePersistMapper(state, defaults) {
120
- return {
121
- $serializeState() {
122
- const out = {};
123
- for (const key in state) {
124
- const item = state[key];
125
- let value;
126
- if ((0, import_vue.isRef)(item)) {
127
- value = item.value;
128
- } else {
129
- value = item;
130
- }
131
- out[key] = (0, import_vue.isReactive)(value) ? (0, import_vue.toRaw)(value) : value;
132
- }
133
- return out;
134
- },
135
- $restoreState(data) {
136
- for (const key in state) {
137
- if (!(key in data)) continue;
138
- const item = state[key];
139
- if ((0, import_vue.isRef)(item)) {
140
- item.value = data[key];
141
- } else if ((0, import_vue.isReactive)(item)) {
142
- Object.assign(item, data[key]);
143
- }
144
- }
145
- },
146
- $reset() {
147
- for (const key in state) {
148
- const item = state[key];
149
- if ((0, import_vue.isRef)(item)) {
150
- item.value = defaults[key];
151
- } else if ((0, import_vue.isReactive)(item)) {
152
- Object.assign(item, defaults[key]);
153
- }
154
- }
155
- }
156
- };
52
+ function deserializeNullableImageData(serialized) {
53
+ if (!serialized) return null;
54
+ return deserializeImageData(serialized);
157
55
  }
158
56
  // Annotate the CommonJS export names for ESM import in node:
159
57
  0 && (module.exports = {
160
- createPiniaSimplePersist,
161
- makeSimplePersistMapper
58
+ deserializeImageData,
59
+ deserializeNullableImageData,
60
+ serializeImageData,
61
+ serializeNullableImageData
162
62
  });
163
63
  //# sourceMappingURL=index.prod.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/plugin.ts","../src/mapper.ts"],"sourcesContent":["export * from './plugin'\nexport { makeSimplePersistMapper } from './mapper'\n","import type { PiniaPluginContext } from 'pinia'\nimport 'pinia'\nimport type { Serializer, StorageLike } from './types'\n\nexport type BaseSimplePersistOptions<Serialized> = {\n storage?: StorageLike\n serializer?: Serializer<Serialized>,\n debounce?: number\n beforeRestore?: (context: PiniaPluginContext) => void\n afterRestore?: (context: PiniaPluginContext) => void,\n onRestoreError?: (err: Error) => void,\n}\n\nexport type GlobalSimplePersistOptions = BaseSimplePersistOptions<any> & {\n makeKey?: (storeId: string) => string,\n}\n\nexport type SimplePersistOptions<Serialized> = BaseSimplePersistOptions<Serialized> & {\n key?: string,\n}\n\nexport function createPiniaSimplePersist(globalOptions: GlobalSimplePersistOptions = {}) {\n const makeKey = globalOptions.makeKey ?? ((id: string) => `pinia-${id}`)\n\n return (context: PiniaPluginContext) => {\n const { store, options } = context\n\n ensureStoreHasRestoreState(store)\n ensureStoreHasSerializeState(store)\n\n const persist = options.persist as SimplePersistOptions<any> | undefined\n if (!persist) return\n\n const {\n key = makeKey(store.$id),\n storage = localStorage,\n serializer = {\n serialize: JSON.stringify,\n deserialize: JSON.parse,\n },\n debounce = 0,\n beforeRestore,\n afterRestore,\n onRestoreError,\n } = { ...globalOptions, ...persist }\n\n const restoreState = () => {\n beforeRestore?.(context)\n\n const stored = storage.getItem(key)\n if (!stored) return\n\n try {\n const data = serializer.deserialize(stored)\n store.$restoreState(data)\n afterRestore?.(context)\n } catch (error) {\n if (onRestoreError) {\n onRestoreError(error instanceof Error ? error : new Error(String(error)))\n } else {\n throw error\n }\n }\n }\n\n const saveState = () => {\n const state = store.$serializeState()\n const serialized = serializer.serialize(state)\n storage.setItem(key, serialized)\n }\n\n let finalSave = saveState\n let cleanupDebounce: (() => void) | undefined\n\n if (debounce) {\n const { debouncedFn, cleanup } = makeDebounce(saveState, debounce)\n finalSave = debouncedFn\n cleanupDebounce = cleanup\n }\n\n // Watch for changes and persist\n const unsubscribe = store.$subscribe(() => {\n finalSave()\n }, { detached: true })\n\n // Cleanup on store disposal\n const originalDispose = store.$dispose\n store.$dispose = function() {\n unsubscribe()\n cleanupDebounce?.()\n originalDispose.call(this)\n }\n\n // Restore state on initialization\n restoreState()\n }\n}\n\nconst makeDebounce = <T extends () => void>(\n callback: T,\n waitFor: number,\n) => {\n let timeout: ReturnType<typeof setTimeout> | undefined\n\n const debouncedFn = (): void => {\n if (timeout) clearTimeout(timeout)\n timeout = setTimeout(() => {\n callback()\n }, waitFor)\n }\n\n const cleanup = (): void => {\n if (timeout) {\n clearTimeout(timeout)\n timeout = undefined\n }\n }\n\n return { debouncedFn, cleanup }\n}\n\nfunction ensureStoreHasRestoreState<T>(store: T): asserts store is T & { $restoreState: (data: any) => void } {\n if (typeof (store as any).$restoreState !== 'function') {\n throw new Error('A store using pinia-simple-persist must have a $restoreState() method')\n }\n}\n\nfunction ensureStoreHasSerializeState<T>(store: T): asserts store is T & { $serializeState: () => any } {\n if (typeof (store as any).$serializeState !== 'function') {\n throw new Error('A store using pinia-simple-persist must have a $serializeState() method')\n }\n}\n","import type { Ref } from 'vue'\nimport { toRaw, isRef, isReactive } from 'vue'\n\ntype RefOrReactive<T> = Ref<T> | T\n\nexport function makeSimplePersistMapper<T extends Record<string, any>>(\n state: { [K in keyof T]: RefOrReactive<T[K]> },\n defaults: T,\n) {\n return {\n $serializeState(): T {\n const out = {} as T\n for (const key in state) {\n const item = state[key]\n let value: any\n\n if (isRef(item)) {\n value = item.value\n } else {\n value = item\n }\n\n out[key] = isReactive(value) ? toRaw(value) : value\n }\n return out\n },\n\n $restoreState(data: T) {\n for (const key in state) {\n if (!(key in data)) continue\n\n const item = state[key]\n\n if (isRef(item)) {\n item.value = data[key]\n } else if (isReactive(item)) {\n Object.assign(item, data[key])\n }\n }\n },\n\n $reset() {\n for (const key in state) {\n const item = state[key]\n\n if (isRef(item)) {\n item.value = defaults[key]\n } else if (isReactive(item)) {\n Object.assign(item, defaults[key])\n }\n }\n },\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/ImageData/serialization.ts"],"sourcesContent":["export * from './ImageData/serialization'\n","export type SerializedImageData = {\n width: number,\n height: number,\n data: string,\n}\n\n/**\n * Serialize for use in JSON. Stored as base64 encoded string.\n */\nexport function serializeImageData<T extends ImageData>(imageData: T): SerializedImageData {\n const binary = String.fromCharCode(...new Uint8Array(imageData.data.buffer))\n const base64 = btoa(binary)\n\n return {\n width: imageData.width,\n height: imageData.height,\n data: base64,\n }\n}\n\nexport function serializeNullableImageData<T extends ImageData | null>(imageData: T): T extends null ? null : SerializedImageData {\n if (!imageData) return null as any\n\n return serializeImageData(imageData) as any\n}\n\nexport function deserializeImageData<T extends SerializedImageData>(serialized: T): ImageData {\n const binary = atob(serialized.data as string)\n const bytes = new Uint8ClampedArray(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n\n return new ImageData(bytes, serialized.width, serialized.height) as any\n}\n\nexport function deserializeNullableImageData<T extends SerializedImageData | null>(serialized: T): T extends null ? null : ImageData {\n if (!serialized) return null as any\n return deserializeImageData(serialized) as any\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACSO,SAAS,mBAAwC,WAAmC;AACzF,QAAM,SAAS,OAAO,aAAa,GAAG,IAAI,WAAW,UAAU,KAAK,MAAM,CAAC;AAC3E,QAAM,SAAS,KAAK,MAAM;AAE1B,SAAO;AAAA,IACL,OAAO,UAAU;AAAA,IACjB,QAAQ,UAAU;AAAA,IAClB,MAAM;AAAA,EACR;AACF;AAEO,SAAS,2BAAuD,WAA2D;AAChI,MAAI,CAAC,UAAW,QAAO;AAEvB,SAAO,mBAAmB,SAAS;AACrC;AAEO,SAAS,qBAAoD,YAA0B;AAC5F,QAAM,SAAS,KAAK,WAAW,IAAc;AAC7C,QAAM,QAAQ,IAAI,kBAAkB,OAAO,MAAM;AACjD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AAEA,SAAO,IAAI,UAAU,OAAO,WAAW,OAAO,WAAW,MAAM;AACjE;AAEO,SAAS,6BAAmE,YAAkD;AACnI,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,qBAAqB,UAAU;AACxC;","names":[]}
@@ -1,68 +1,14 @@
1
- import { PiniaPluginContext } from 'pinia';
2
- import { Ref } from 'vue';
3
-
1
+ type SerializedImageData = {
2
+ width: number;
3
+ height: number;
4
+ data: string;
5
+ };
4
6
  /**
5
- * Synchronous storage based on Web Storage API.
6
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Storage
7
+ * Serialize for use in JSON. Stored as base64 encoded string.
7
8
  */
8
- interface StorageLike {
9
- /**
10
- * Get a key's value if it exists.
11
- */
12
- getItem: (key: string) => string | null;
13
- /**
14
- * Set a key with a value, or update it if it exists.
15
- */
16
- setItem: (key: string, value: string) => void;
17
- }
18
- interface Serializer<T> {
19
- /**
20
- * Serialize state into string before storing.
21
- * @default JSON.stringify
22
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
23
- */
24
- serialize: (data: T) => string;
25
- /**
26
- * Deserializes string into state before hydrating.
27
- * @default JSON.parse
28
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
29
- */
30
- deserialize: (data: string) => T;
31
- }
32
- declare module 'pinia' {
33
- interface DefineStoreOptionsBase<S, Store> {
34
- persist?: SimplePersistOptions<any> | boolean;
35
- }
36
- interface PiniaCustomProperties {
37
- $persist: () => void;
38
- $restoreState?: (data: any) => void;
39
- $serializeState?: () => any;
40
- }
41
- }
42
-
43
- type BaseSimplePersistOptions<Serialized> = {
44
- storage?: StorageLike;
45
- serializer?: Serializer<Serialized>;
46
- debounce?: number;
47
- beforeRestore?: (context: PiniaPluginContext) => void;
48
- afterRestore?: (context: PiniaPluginContext) => void;
49
- onRestoreError?: (err: Error) => void;
50
- };
51
- type GlobalSimplePersistOptions = BaseSimplePersistOptions<any> & {
52
- makeKey?: (storeId: string) => string;
53
- };
54
- type SimplePersistOptions<Serialized> = BaseSimplePersistOptions<Serialized> & {
55
- key?: string;
56
- };
57
- declare function createPiniaSimplePersist(globalOptions?: GlobalSimplePersistOptions): (context: PiniaPluginContext) => void;
58
-
59
- type RefOrReactive<T> = Ref<T> | T;
60
- declare function makeSimplePersistMapper<T extends Record<string, any>>(state: {
61
- [K in keyof T]: RefOrReactive<T[K]>;
62
- }, defaults: T): {
63
- $serializeState(): T;
64
- $restoreState(data: T): void;
65
- $reset(): void;
66
- };
9
+ declare function serializeImageData<T extends ImageData>(imageData: T): SerializedImageData;
10
+ declare function serializeNullableImageData<T extends ImageData | null>(imageData: T): T extends null ? null : SerializedImageData;
11
+ declare function deserializeImageData<T extends SerializedImageData>(serialized: T): ImageData;
12
+ declare function deserializeNullableImageData<T extends SerializedImageData | null>(serialized: T): T extends null ? null : ImageData;
67
13
 
68
- export { type BaseSimplePersistOptions, type GlobalSimplePersistOptions, type SimplePersistOptions, createPiniaSimplePersist, makeSimplePersistMapper };
14
+ export { type SerializedImageData, deserializeImageData, deserializeNullableImageData, serializeImageData, serializeNullableImageData };
@@ -1,135 +1,33 @@
1
- // src/plugin.ts
2
- import "pinia";
3
- function createPiniaSimplePersist(globalOptions = {}) {
4
- const makeKey = globalOptions.makeKey ?? ((id) => `pinia-${id}`);
5
- return (context) => {
6
- const { store, options } = context;
7
- ensureStoreHasRestoreState(store);
8
- ensureStoreHasSerializeState(store);
9
- const persist = options.persist;
10
- if (!persist) return;
11
- const {
12
- key = makeKey(store.$id),
13
- storage = localStorage,
14
- serializer = {
15
- serialize: JSON.stringify,
16
- deserialize: JSON.parse
17
- },
18
- debounce = 0,
19
- beforeRestore,
20
- afterRestore,
21
- onRestoreError
22
- } = { ...globalOptions, ...persist };
23
- const restoreState = () => {
24
- beforeRestore?.(context);
25
- const stored = storage.getItem(key);
26
- if (!stored) return;
27
- try {
28
- const data = serializer.deserialize(stored);
29
- store.$restoreState(data);
30
- afterRestore?.(context);
31
- } catch (error) {
32
- if (onRestoreError) {
33
- onRestoreError(error instanceof Error ? error : new Error(String(error)));
34
- } else {
35
- throw error;
36
- }
37
- }
38
- };
39
- const saveState = () => {
40
- const state = store.$serializeState();
41
- const serialized = serializer.serialize(state);
42
- storage.setItem(key, serialized);
43
- };
44
- let finalSave = saveState;
45
- let cleanupDebounce;
46
- if (debounce) {
47
- const { debouncedFn, cleanup } = makeDebounce(saveState, debounce);
48
- finalSave = debouncedFn;
49
- cleanupDebounce = cleanup;
50
- }
51
- const unsubscribe = store.$subscribe(() => {
52
- finalSave();
53
- }, { detached: true });
54
- const originalDispose = store.$dispose;
55
- store.$dispose = function() {
56
- unsubscribe();
57
- cleanupDebounce?.();
58
- originalDispose.call(this);
59
- };
60
- restoreState();
1
+ // src/ImageData/serialization.ts
2
+ function serializeImageData(imageData) {
3
+ const binary = String.fromCharCode(...new Uint8Array(imageData.data.buffer));
4
+ const base64 = btoa(binary);
5
+ return {
6
+ width: imageData.width,
7
+ height: imageData.height,
8
+ data: base64
61
9
  };
62
10
  }
63
- var makeDebounce = (callback, waitFor) => {
64
- let timeout;
65
- const debouncedFn = () => {
66
- if (timeout) clearTimeout(timeout);
67
- timeout = setTimeout(() => {
68
- callback();
69
- }, waitFor);
70
- };
71
- const cleanup = () => {
72
- if (timeout) {
73
- clearTimeout(timeout);
74
- timeout = void 0;
75
- }
76
- };
77
- return { debouncedFn, cleanup };
78
- };
79
- function ensureStoreHasRestoreState(store) {
80
- if (typeof store.$restoreState !== "function") {
81
- throw new Error("A store using pinia-simple-persist must have a $restoreState() method");
82
- }
11
+ function serializeNullableImageData(imageData) {
12
+ if (!imageData) return null;
13
+ return serializeImageData(imageData);
83
14
  }
84
- function ensureStoreHasSerializeState(store) {
85
- if (typeof store.$serializeState !== "function") {
86
- throw new Error("A store using pinia-simple-persist must have a $serializeState() method");
15
+ function deserializeImageData(serialized) {
16
+ const binary = atob(serialized.data);
17
+ const bytes = new Uint8ClampedArray(binary.length);
18
+ for (let i = 0; i < binary.length; i++) {
19
+ bytes[i] = binary.charCodeAt(i);
87
20
  }
21
+ return new ImageData(bytes, serialized.width, serialized.height);
88
22
  }
89
-
90
- // src/mapper.ts
91
- import { toRaw, isRef, isReactive } from "vue";
92
- function makeSimplePersistMapper(state, defaults) {
93
- return {
94
- $serializeState() {
95
- const out = {};
96
- for (const key in state) {
97
- const item = state[key];
98
- let value;
99
- if (isRef(item)) {
100
- value = item.value;
101
- } else {
102
- value = item;
103
- }
104
- out[key] = isReactive(value) ? toRaw(value) : value;
105
- }
106
- return out;
107
- },
108
- $restoreState(data) {
109
- for (const key in state) {
110
- if (!(key in data)) continue;
111
- const item = state[key];
112
- if (isRef(item)) {
113
- item.value = data[key];
114
- } else if (isReactive(item)) {
115
- Object.assign(item, data[key]);
116
- }
117
- }
118
- },
119
- $reset() {
120
- for (const key in state) {
121
- const item = state[key];
122
- if (isRef(item)) {
123
- item.value = defaults[key];
124
- } else if (isReactive(item)) {
125
- Object.assign(item, defaults[key]);
126
- }
127
- }
128
- }
129
- };
23
+ function deserializeNullableImageData(serialized) {
24
+ if (!serialized) return null;
25
+ return deserializeImageData(serialized);
130
26
  }
131
27
  export {
132
- createPiniaSimplePersist,
133
- makeSimplePersistMapper
28
+ deserializeImageData,
29
+ deserializeNullableImageData,
30
+ serializeImageData,
31
+ serializeNullableImageData
134
32
  };
135
33
  //# sourceMappingURL=index.prod.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugin.ts","../src/mapper.ts"],"sourcesContent":["import type { PiniaPluginContext } from 'pinia'\nimport 'pinia'\nimport type { Serializer, StorageLike } from './types'\n\nexport type BaseSimplePersistOptions<Serialized> = {\n storage?: StorageLike\n serializer?: Serializer<Serialized>,\n debounce?: number\n beforeRestore?: (context: PiniaPluginContext) => void\n afterRestore?: (context: PiniaPluginContext) => void,\n onRestoreError?: (err: Error) => void,\n}\n\nexport type GlobalSimplePersistOptions = BaseSimplePersistOptions<any> & {\n makeKey?: (storeId: string) => string,\n}\n\nexport type SimplePersistOptions<Serialized> = BaseSimplePersistOptions<Serialized> & {\n key?: string,\n}\n\nexport function createPiniaSimplePersist(globalOptions: GlobalSimplePersistOptions = {}) {\n const makeKey = globalOptions.makeKey ?? ((id: string) => `pinia-${id}`)\n\n return (context: PiniaPluginContext) => {\n const { store, options } = context\n\n ensureStoreHasRestoreState(store)\n ensureStoreHasSerializeState(store)\n\n const persist = options.persist as SimplePersistOptions<any> | undefined\n if (!persist) return\n\n const {\n key = makeKey(store.$id),\n storage = localStorage,\n serializer = {\n serialize: JSON.stringify,\n deserialize: JSON.parse,\n },\n debounce = 0,\n beforeRestore,\n afterRestore,\n onRestoreError,\n } = { ...globalOptions, ...persist }\n\n const restoreState = () => {\n beforeRestore?.(context)\n\n const stored = storage.getItem(key)\n if (!stored) return\n\n try {\n const data = serializer.deserialize(stored)\n store.$restoreState(data)\n afterRestore?.(context)\n } catch (error) {\n if (onRestoreError) {\n onRestoreError(error instanceof Error ? error : new Error(String(error)))\n } else {\n throw error\n }\n }\n }\n\n const saveState = () => {\n const state = store.$serializeState()\n const serialized = serializer.serialize(state)\n storage.setItem(key, serialized)\n }\n\n let finalSave = saveState\n let cleanupDebounce: (() => void) | undefined\n\n if (debounce) {\n const { debouncedFn, cleanup } = makeDebounce(saveState, debounce)\n finalSave = debouncedFn\n cleanupDebounce = cleanup\n }\n\n // Watch for changes and persist\n const unsubscribe = store.$subscribe(() => {\n finalSave()\n }, { detached: true })\n\n // Cleanup on store disposal\n const originalDispose = store.$dispose\n store.$dispose = function() {\n unsubscribe()\n cleanupDebounce?.()\n originalDispose.call(this)\n }\n\n // Restore state on initialization\n restoreState()\n }\n}\n\nconst makeDebounce = <T extends () => void>(\n callback: T,\n waitFor: number,\n) => {\n let timeout: ReturnType<typeof setTimeout> | undefined\n\n const debouncedFn = (): void => {\n if (timeout) clearTimeout(timeout)\n timeout = setTimeout(() => {\n callback()\n }, waitFor)\n }\n\n const cleanup = (): void => {\n if (timeout) {\n clearTimeout(timeout)\n timeout = undefined\n }\n }\n\n return { debouncedFn, cleanup }\n}\n\nfunction ensureStoreHasRestoreState<T>(store: T): asserts store is T & { $restoreState: (data: any) => void } {\n if (typeof (store as any).$restoreState !== 'function') {\n throw new Error('A store using pinia-simple-persist must have a $restoreState() method')\n }\n}\n\nfunction ensureStoreHasSerializeState<T>(store: T): asserts store is T & { $serializeState: () => any } {\n if (typeof (store as any).$serializeState !== 'function') {\n throw new Error('A store using pinia-simple-persist must have a $serializeState() method')\n }\n}\n","import type { Ref } from 'vue'\nimport { toRaw, isRef, isReactive } from 'vue'\n\ntype RefOrReactive<T> = Ref<T> | T\n\nexport function makeSimplePersistMapper<T extends Record<string, any>>(\n state: { [K in keyof T]: RefOrReactive<T[K]> },\n defaults: T,\n) {\n return {\n $serializeState(): T {\n const out = {} as T\n for (const key in state) {\n const item = state[key]\n let value: any\n\n if (isRef(item)) {\n value = item.value\n } else {\n value = item\n }\n\n out[key] = isReactive(value) ? toRaw(value) : value\n }\n return out\n },\n\n $restoreState(data: T) {\n for (const key in state) {\n if (!(key in data)) continue\n\n const item = state[key]\n\n if (isRef(item)) {\n item.value = data[key]\n } else if (isReactive(item)) {\n Object.assign(item, data[key])\n }\n }\n },\n\n $reset() {\n for (const key in state) {\n const item = state[key]\n\n if (isRef(item)) {\n item.value = defaults[key]\n } else if (isReactive(item)) {\n Object.assign(item, defaults[key])\n }\n }\n },\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/ImageData/serialization.ts"],"sourcesContent":["export type SerializedImageData = {\n width: number,\n height: number,\n data: string,\n}\n\n/**\n * Serialize for use in JSON. Stored as base64 encoded string.\n */\nexport function serializeImageData<T extends ImageData>(imageData: T): SerializedImageData {\n const binary = String.fromCharCode(...new Uint8Array(imageData.data.buffer))\n const base64 = btoa(binary)\n\n return {\n width: imageData.width,\n height: imageData.height,\n data: base64,\n }\n}\n\nexport function serializeNullableImageData<T extends ImageData | null>(imageData: T): T extends null ? null : SerializedImageData {\n if (!imageData) return null as any\n\n return serializeImageData(imageData) as any\n}\n\nexport function deserializeImageData<T extends SerializedImageData>(serialized: T): ImageData {\n const binary = atob(serialized.data as string)\n const bytes = new Uint8ClampedArray(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n\n return new ImageData(bytes, serialized.width, serialized.height) as any\n}\n\nexport function deserializeNullableImageData<T extends SerializedImageData | null>(serialized: T): T extends null ? null : ImageData {\n if (!serialized) return null as any\n return deserializeImageData(serialized) as any\n}\n"],"mappings":";AASO,SAAS,mBAAwC,WAAmC;AACzF,QAAM,SAAS,OAAO,aAAa,GAAG,IAAI,WAAW,UAAU,KAAK,MAAM,CAAC;AAC3E,QAAM,SAAS,KAAK,MAAM;AAE1B,SAAO;AAAA,IACL,OAAO,UAAU;AAAA,IACjB,QAAQ,UAAU;AAAA,IAClB,MAAM;AAAA,EACR;AACF;AAEO,SAAS,2BAAuD,WAA2D;AAChI,MAAI,CAAC,UAAW,QAAO;AAEvB,SAAO,mBAAmB,SAAS;AACrC;AAEO,SAAS,qBAAoD,YAA0B;AAC5F,QAAM,SAAS,KAAK,WAAW,IAAc;AAC7C,QAAM,QAAQ,IAAI,kBAAkB,OAAO,MAAM;AACjD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AAEA,SAAO,IAAI,UAAU,OAAO,WAAW,OAAO,WAAW,MAAM;AACjE;AAEO,SAAS,6BAAmE,YAAkD;AACnI,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,qBAAqB,UAAU;AACxC;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pixel-data-js",
3
3
  "type": "module",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "packageManager": "pnpm@10.30.0",
6
6
  "description": "JS Pixel and ImageData operations",
7
7
  "author": {