even-toolkit 1.5.9 → 1.6.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.
@@ -1,48 +1,18 @@
1
1
  /**
2
2
  * Persistent storage for Even Hub apps.
3
3
  *
4
- * The Even Hub WebView doesn't persist browser localStorage across app restarts.
5
- * This module uses the SDK's `bridge.setLocalStorage/getLocalStorage` which DO persist,
6
- * with browser localStorage as a sync-read cache and fallback for web/dev.
7
- *
8
- * Usage:
9
- * import { storageSet, storageGetSync, hydrateFromSDK } from 'even-toolkit/storage';
10
- *
11
- * // In main.tsx — hydrate before render:
12
- * hydrateFromSDK(['my-app:settings', 'my-app:data']).finally(() => {
13
- * createRoot(...).render(<App />);
14
- * });
15
- *
16
- * // Read (synchronous):
17
- * const data = storageGetSync<MyData>('my-app:data', defaultValue);
18
- *
19
- * // Write (dual-write to localStorage + SDK bridge):
20
- * storageSet('my-app:data', data);
21
- */
22
- /**
23
- * Read a JSON value synchronously from browser localStorage.
24
- * Call `hydrateFromSDK()` at startup to ensure localStorage has the latest SDK data.
25
- */
26
- export declare function storageGetSync<T>(key: string, fallback: T): T;
27
- /**
28
- * Write a JSON-serializable value to both localStorage and SDK bridge.
29
- */
30
- export declare function storageSet(key: string, value: unknown): void;
31
- /**
32
- * Write a raw string value to both localStorage and SDK bridge.
33
- * Use for pre-serialized or encrypted values that shouldn't be double-stringified.
34
- */
35
- export declare function storageSetRaw(key: string, value: string): void;
36
- /**
37
- * Remove a key from both localStorage and SDK bridge.
38
- */
39
- export declare function storageRemove(key: string): void;
40
- /**
41
- * Hydrate browser localStorage from SDK bridge on app startup.
42
- * Call once before React renders so `storageGetSync` reads fresh data.
43
- * Gets the raw SDK bridge directly (doesn't depend on useGlasses).
44
- *
45
- * @param keys - All storage keys used by the app
4
+ * Uses the SDK bridge's setLocalStorage/getLocalStorage directly.
5
+ * No browser localStorage, no caching — the SDK bridge is the single source of truth.
6
+ * Falls back silently when SDK is not available (web/dev).
46
7
  */
47
- export declare function hydrateFromSDK(keys: string[]): Promise<void>;
8
+ /** Read a JSON value from SDK storage */
9
+ export declare function storageGet<T>(key: string, fallback: T): Promise<T>;
10
+ /** Read a raw string from SDK storage */
11
+ export declare function storageGetRaw(key: string): Promise<string>;
12
+ /** Write a JSON value to SDK storage */
13
+ export declare function storageSet(key: string, value: unknown): Promise<void>;
14
+ /** Write a raw string to SDK storage */
15
+ export declare function storageSetRaw(key: string, value: string): Promise<void>;
16
+ /** Remove a key from SDK storage */
17
+ export declare function storageRemove(key: string): Promise<void>;
48
18
  //# sourceMappingURL=storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../glasses/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAqCH;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAM7D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAO5D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAM9D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAM/C;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAYlE"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../glasses/storage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAwBH,yCAAyC;AACzC,wBAAsB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAQxE;AAED,yCAAyC;AACzC,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQhE;AAED,wCAAwC;AACxC,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3E;AAED,wCAAwC;AACxC,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7E;AAED,oCAAoC;AACpC,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM9D"}
@@ -1,53 +1,27 @@
1
1
  /**
2
2
  * Persistent storage for Even Hub apps.
3
3
  *
4
- * The Even Hub WebView doesn't persist browser localStorage across app restarts.
5
- * This module uses the SDK's `bridge.setLocalStorage/getLocalStorage` which DO persist,
6
- * with browser localStorage as a sync-read cache and fallback for web/dev.
7
- *
8
- * Usage:
9
- * import { storageSet, storageGetSync, hydrateFromSDK } from 'even-toolkit/storage';
10
- *
11
- * // In main.tsx — hydrate before render:
12
- * hydrateFromSDK(['my-app:settings', 'my-app:data']).finally(() => {
13
- * createRoot(...).render(<App />);
14
- * });
15
- *
16
- * // Read (synchronous):
17
- * const data = storageGetSync<MyData>('my-app:data', defaultValue);
18
- *
19
- * // Write (dual-write to localStorage + SDK bridge):
20
- * storageSet('my-app:data', data);
21
- */
22
- /**
23
- * Get a bridge object that has setLocalStorage/getLocalStorage.
24
- * Checks window.__evenBridge (our wrapper) first,
25
- * then tries the raw SDK bridge directly via waitForEvenAppBridge.
4
+ * Uses the SDK bridge's setLocalStorage/getLocalStorage directly.
5
+ * No browser localStorage, no caching — the SDK bridge is the single source of truth.
6
+ * Falls back silently when SDK is not available (web/dev).
26
7
  */
27
8
  function getBridge() {
28
9
  const bridge = window.__evenBridge;
29
10
  if (bridge?.setLocalStorage)
30
11
  return bridge;
31
- // Also check raw bridge exposed on the wrapper
32
12
  if (bridge?.rawBridge?.setLocalStorage)
33
13
  return bridge.rawBridge;
34
14
  return null;
35
15
  }
36
- /**
37
- * Try to get a raw SDK bridge for hydration (before useGlasses sets window.__evenBridge).
38
- * Returns null if SDK is not available (web/dev environment).
39
- */
40
- async function getRawBridgeForHydration() {
41
- // If our wrapper is already set, use it
16
+ async function getRawBridge() {
42
17
  const existing = getBridge();
43
18
  if (existing)
44
19
  return existing;
45
- // Try to get raw bridge directly from the SDK
46
20
  try {
47
21
  const { EvenBetterSdk } = await import('@jappyjan/even-better-sdk');
48
22
  const raw = await Promise.race([
49
23
  EvenBetterSdk.getRawBridge(),
50
- new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 2000)),
24
+ new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 3000)),
51
25
  ]);
52
26
  return raw;
53
27
  }
@@ -55,76 +29,59 @@ async function getRawBridgeForHydration() {
55
29
  return null;
56
30
  }
57
31
  }
58
- /**
59
- * Read a JSON value synchronously from browser localStorage.
60
- * Call `hydrateFromSDK()` at startup to ensure localStorage has the latest SDK data.
61
- */
62
- export function storageGetSync(key, fallback) {
32
+ /** Read a JSON value from SDK storage */
33
+ export async function storageGet(key, fallback) {
34
+ const bridge = getBridge() ?? await getRawBridge();
35
+ if (!bridge?.getLocalStorage)
36
+ return fallback;
63
37
  try {
64
- const raw = localStorage.getItem(key);
65
- if (raw)
38
+ const raw = await bridge.getLocalStorage(key);
39
+ if (raw && raw !== '')
66
40
  return JSON.parse(raw);
67
41
  }
68
42
  catch { /* ignore */ }
69
43
  return fallback;
70
44
  }
71
- /**
72
- * Write a JSON-serializable value to both localStorage and SDK bridge.
73
- */
74
- export function storageSet(key, value) {
75
- const json = JSON.stringify(value);
45
+ /** Read a raw string from SDK storage */
46
+ export async function storageGetRaw(key) {
47
+ const bridge = getBridge() ?? await getRawBridge();
48
+ if (!bridge?.getLocalStorage)
49
+ return '';
76
50
  try {
77
- localStorage.setItem(key, json);
51
+ return await bridge.getLocalStorage(key);
78
52
  }
79
- catch { /* ignore */ }
80
- const bridge = getBridge();
81
- if (bridge?.setLocalStorage) {
82
- bridge.setLocalStorage(key, json).catch(() => { });
53
+ catch {
54
+ return '';
83
55
  }
84
56
  }
85
- /**
86
- * Write a raw string value to both localStorage and SDK bridge.
87
- * Use for pre-serialized or encrypted values that shouldn't be double-stringified.
88
- */
89
- export function storageSetRaw(key, value) {
57
+ /** Write a JSON value to SDK storage */
58
+ export async function storageSet(key, value) {
59
+ const bridge = getBridge();
60
+ if (!bridge?.setLocalStorage)
61
+ return;
90
62
  try {
91
- localStorage.setItem(key, value);
63
+ await bridge.setLocalStorage(key, JSON.stringify(value));
92
64
  }
93
65
  catch { /* ignore */ }
94
- const bridge = getBridge();
95
- if (bridge?.setLocalStorage) {
96
- bridge.setLocalStorage(key, value).catch(() => { });
97
- }
98
66
  }
99
- /**
100
- * Remove a key from both localStorage and SDK bridge.
101
- */
102
- export function storageRemove(key) {
103
- localStorage.removeItem(key);
67
+ /** Write a raw string to SDK storage */
68
+ export async function storageSetRaw(key, value) {
104
69
  const bridge = getBridge();
105
- if (bridge?.setLocalStorage) {
106
- bridge.setLocalStorage(key, '').catch(() => { });
70
+ if (!bridge?.setLocalStorage)
71
+ return;
72
+ try {
73
+ await bridge.setLocalStorage(key, value);
107
74
  }
75
+ catch { /* ignore */ }
108
76
  }
109
- /**
110
- * Hydrate browser localStorage from SDK bridge on app startup.
111
- * Call once before React renders so `storageGetSync` reads fresh data.
112
- * Gets the raw SDK bridge directly (doesn't depend on useGlasses).
113
- *
114
- * @param keys - All storage keys used by the app
115
- */
116
- export async function hydrateFromSDK(keys) {
117
- const bridge = await getRawBridgeForHydration();
118
- if (!bridge?.getLocalStorage)
77
+ /** Remove a key from SDK storage */
78
+ export async function storageRemove(key) {
79
+ const bridge = getBridge();
80
+ if (!bridge?.setLocalStorage)
119
81
  return;
120
- for (const key of keys) {
121
- try {
122
- const value = await bridge.getLocalStorage(key);
123
- if (value && value !== '') {
124
- localStorage.setItem(key, value);
125
- }
126
- }
127
- catch { /* ignore */ }
82
+ try {
83
+ await bridge.setLocalStorage(key, '');
128
84
  }
85
+ catch { /* ignore */ }
129
86
  }
130
87
  //# sourceMappingURL=storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../glasses/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../glasses/storage.ts"],"names":[],"mappings":"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"}
@@ -1,53 +1,26 @@
1
1
  /**
2
2
  * Persistent storage for Even Hub apps.
3
3
  *
4
- * The Even Hub WebView doesn't persist browser localStorage across app restarts.
5
- * This module uses the SDK's `bridge.setLocalStorage/getLocalStorage` which DO persist,
6
- * with browser localStorage as a sync-read cache and fallback for web/dev.
7
- *
8
- * Usage:
9
- * import { storageSet, storageGetSync, hydrateFromSDK } from 'even-toolkit/storage';
10
- *
11
- * // In main.tsx — hydrate before render:
12
- * hydrateFromSDK(['my-app:settings', 'my-app:data']).finally(() => {
13
- * createRoot(...).render(<App />);
14
- * });
15
- *
16
- * // Read (synchronous):
17
- * const data = storageGetSync<MyData>('my-app:data', defaultValue);
18
- *
19
- * // Write (dual-write to localStorage + SDK bridge):
20
- * storageSet('my-app:data', data);
4
+ * Uses the SDK bridge's setLocalStorage/getLocalStorage directly.
5
+ * No browser localStorage, no caching — the SDK bridge is the single source of truth.
6
+ * Falls back silently when SDK is not available (web/dev).
21
7
  */
22
8
 
23
- /**
24
- * Get a bridge object that has setLocalStorage/getLocalStorage.
25
- * Checks window.__evenBridge (our wrapper) first,
26
- * then tries the raw SDK bridge directly via waitForEvenAppBridge.
27
- */
28
9
  function getBridge(): any {
29
10
  const bridge = (window as any).__evenBridge;
30
11
  if (bridge?.setLocalStorage) return bridge;
31
- // Also check raw bridge exposed on the wrapper
32
12
  if (bridge?.rawBridge?.setLocalStorage) return bridge.rawBridge;
33
13
  return null;
34
14
  }
35
15
 
36
- /**
37
- * Try to get a raw SDK bridge for hydration (before useGlasses sets window.__evenBridge).
38
- * Returns null if SDK is not available (web/dev environment).
39
- */
40
- async function getRawBridgeForHydration(): Promise<any> {
41
- // If our wrapper is already set, use it
16
+ async function getRawBridge(): Promise<any> {
42
17
  const existing = getBridge();
43
18
  if (existing) return existing;
44
-
45
- // Try to get raw bridge directly from the SDK
46
19
  try {
47
20
  const { EvenBetterSdk } = await import('@jappyjan/even-better-sdk');
48
21
  const raw = await Promise.race([
49
22
  EvenBetterSdk.getRawBridge(),
50
- new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 2000)),
23
+ new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 3000)),
51
24
  ]);
52
25
  return raw;
53
26
  } catch {
@@ -55,70 +28,51 @@ async function getRawBridgeForHydration(): Promise<any> {
55
28
  }
56
29
  }
57
30
 
58
- /**
59
- * Read a JSON value synchronously from browser localStorage.
60
- * Call `hydrateFromSDK()` at startup to ensure localStorage has the latest SDK data.
61
- */
62
- export function storageGetSync<T>(key: string, fallback: T): T {
31
+ /** Read a JSON value from SDK storage */
32
+ export async function storageGet<T>(key: string, fallback: T): Promise<T> {
33
+ const bridge = getBridge() ?? await getRawBridge();
34
+ if (!bridge?.getLocalStorage) return fallback;
63
35
  try {
64
- const raw = localStorage.getItem(key);
65
- if (raw) return JSON.parse(raw);
36
+ const raw = await bridge.getLocalStorage(key);
37
+ if (raw && raw !== '') return JSON.parse(raw);
66
38
  } catch { /* ignore */ }
67
39
  return fallback;
68
40
  }
69
41
 
70
- /**
71
- * Write a JSON-serializable value to both localStorage and SDK bridge.
72
- */
73
- export function storageSet(key: string, value: unknown): void {
74
- const json = JSON.stringify(value);
75
- try { localStorage.setItem(key, json); } catch { /* ignore */ }
76
- const bridge = getBridge();
77
- if (bridge?.setLocalStorage) {
78
- bridge.setLocalStorage(key, json).catch(() => {});
42
+ /** Read a raw string from SDK storage */
43
+ export async function storageGetRaw(key: string): Promise<string> {
44
+ const bridge = getBridge() ?? await getRawBridge();
45
+ if (!bridge?.getLocalStorage) return '';
46
+ try {
47
+ return await bridge.getLocalStorage(key);
48
+ } catch {
49
+ return '';
79
50
  }
80
51
  }
81
52
 
82
- /**
83
- * Write a raw string value to both localStorage and SDK bridge.
84
- * Use for pre-serialized or encrypted values that shouldn't be double-stringified.
85
- */
86
- export function storageSetRaw(key: string, value: string): void {
87
- try { localStorage.setItem(key, value); } catch { /* ignore */ }
53
+ /** Write a JSON value to SDK storage */
54
+ export async function storageSet(key: string, value: unknown): Promise<void> {
88
55
  const bridge = getBridge();
89
- if (bridge?.setLocalStorage) {
90
- bridge.setLocalStorage(key, value).catch(() => {});
91
- }
56
+ if (!bridge?.setLocalStorage) return;
57
+ try {
58
+ await bridge.setLocalStorage(key, JSON.stringify(value));
59
+ } catch { /* ignore */ }
92
60
  }
93
61
 
94
- /**
95
- * Remove a key from both localStorage and SDK bridge.
96
- */
97
- export function storageRemove(key: string): void {
98
- localStorage.removeItem(key);
62
+ /** Write a raw string to SDK storage */
63
+ export async function storageSetRaw(key: string, value: string): Promise<void> {
99
64
  const bridge = getBridge();
100
- if (bridge?.setLocalStorage) {
101
- bridge.setLocalStorage(key, '').catch(() => {});
102
- }
65
+ if (!bridge?.setLocalStorage) return;
66
+ try {
67
+ await bridge.setLocalStorage(key, value);
68
+ } catch { /* ignore */ }
103
69
  }
104
70
 
105
- /**
106
- * Hydrate browser localStorage from SDK bridge on app startup.
107
- * Call once before React renders so `storageGetSync` reads fresh data.
108
- * Gets the raw SDK bridge directly (doesn't depend on useGlasses).
109
- *
110
- * @param keys - All storage keys used by the app
111
- */
112
- export async function hydrateFromSDK(keys: string[]): Promise<void> {
113
- const bridge = await getRawBridgeForHydration();
114
- if (!bridge?.getLocalStorage) return;
115
-
116
- for (const key of keys) {
117
- try {
118
- const value = await bridge.getLocalStorage(key);
119
- if (value && value !== '') {
120
- localStorage.setItem(key, value);
121
- }
122
- } catch { /* ignore */ }
123
- }
71
+ /** Remove a key from SDK storage */
72
+ export async function storageRemove(key: string): Promise<void> {
73
+ const bridge = getBridge();
74
+ if (!bridge?.setLocalStorage) return;
75
+ try {
76
+ await bridge.setLocalStorage(key, '');
77
+ } catch { /* ignore */ }
124
78
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "even-toolkit",
3
- "version": "1.5.9",
3
+ "version": "1.6.0",
4
4
  "bin": {
5
5
  "even-toolkit": "./bin/create.js"
6
6
  },