@harborclient/sdk 0.6.17 → 0.7.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.
Files changed (45) hide show
  1. package/dist/components/index.d.ts +0 -1
  2. package/dist/components/index.d.ts.map +1 -1
  3. package/dist/components/index.js +0 -1
  4. package/dist/http/resolveRequest.test.js +1 -2
  5. package/dist/runtime/react.d.ts +0 -6
  6. package/dist/runtime/react.js +2 -70
  7. package/dist/runtime/reactHost.js +0 -52
  8. package/dist/runtime/store.d.ts +0 -101
  9. package/dist/runtime/store.d.ts.map +1 -1
  10. package/dist/runtime/store.js +0 -94
  11. package/dist/runtime/store.ts +0 -203
  12. package/dist/runtime/viewHost.js +1 -2
  13. package/dist/runtime-utils.d.ts +0 -59
  14. package/dist/runtime-utils.d.ts.map +1 -1
  15. package/dist/runtime-utils.js +0 -66
  16. package/dist/runtime-utils.test.js +1 -74
  17. package/dist/storage/index.d.ts +0 -1
  18. package/dist/storage/index.d.ts.map +1 -1
  19. package/dist/storage/index.js +0 -1
  20. package/dist/types.d.ts +0 -14
  21. package/dist/types.d.ts.map +1 -1
  22. package/package.json +7 -35
  23. package/dist/build/index.d.ts +0 -59
  24. package/dist/build/index.d.ts.map +0 -1
  25. package/dist/build/index.js +0 -107
  26. package/dist/components/portalToBody.d.ts +0 -10
  27. package/dist/components/portalToBody.d.ts.map +0 -1
  28. package/dist/components/portalToBody.js +0 -14
  29. package/dist/eslint/index.d.ts +0 -9
  30. package/dist/eslint/index.d.ts.map +0 -1
  31. package/dist/eslint/index.js +0 -18
  32. package/dist/runtime/jsx-runtime-host.d.ts +0 -44
  33. package/dist/runtime/jsx-runtime-host.js +0 -42
  34. package/dist/runtime/react-dom.d.ts +0 -1
  35. package/dist/runtime/react-dom.js +0 -16
  36. package/dist/storage/validate.d.ts +0 -71
  37. package/dist/storage/validate.d.ts.map +0 -1
  38. package/dist/storage/validate.js +0 -111
  39. package/dist/storage/validate.test.d.ts +0 -2
  40. package/dist/storage/validate.test.d.ts.map +0 -1
  41. package/dist/storage/validate.test.js +0 -78
  42. package/dist/store.test.d.ts +0 -2
  43. package/dist/store.test.d.ts.map +0 -1
  44. package/dist/store.test.js +0 -248
  45. package/tsconfig.base.json +0 -15
@@ -1,248 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals';
2
- import { createExternalStore, createStorageStore, setIntervalDisposable, syncOnWindowFocus } from './runtime/store.js';
3
- /**
4
- * Builds an in-memory storage mock for store tests.
5
- *
6
- * @param initial - Seed values keyed by storage key.
7
- */
8
- function createMockStorage(initial = {}) {
9
- const data = { ...initial };
10
- const getMock = jest.fn(async (key) => data[key]);
11
- const setMock = jest.fn(async (key, value) => {
12
- data[key] = value;
13
- });
14
- return {
15
- data,
16
- get: getMock,
17
- set: setMock,
18
- getMock,
19
- setMock
20
- };
21
- }
22
- describe('createExternalStore', () => {
23
- it('notifies subscribers when setState is called', () => {
24
- const store = createExternalStore(0);
25
- const listener = jest.fn();
26
- store.subscribe(listener);
27
- store.setState(1);
28
- expect(listener).toHaveBeenCalledTimes(1);
29
- expect(store.getSnapshot()).toBe(1);
30
- });
31
- });
32
- describe('createStorageStore', () => {
33
- it('starts from parse(undefined)', () => {
34
- const storage = createMockStorage();
35
- const store = createStorageStore({
36
- storage,
37
- key: 'items',
38
- parse: (raw) => (Array.isArray(raw) ? raw : [])
39
- });
40
- expect(store.getSnapshot()).toEqual([]);
41
- });
42
- it('persists and updates the snapshot via set', async () => {
43
- const storage = createMockStorage();
44
- const store = createStorageStore({
45
- storage,
46
- key: 'items',
47
- parse: (raw) => (Array.isArray(raw) ? raw : [])
48
- });
49
- const listener = jest.fn();
50
- store.subscribe(listener);
51
- await store.set(['a']);
52
- expect(store.getSnapshot()).toEqual(['a']);
53
- expect(storage.setMock).toHaveBeenCalledWith('items', ['a']);
54
- expect(listener).toHaveBeenCalledTimes(1);
55
- });
56
- it('skips set when equals reports no change', async () => {
57
- const storage = createMockStorage({ items: ['a'] });
58
- const store = createStorageStore({
59
- storage,
60
- key: 'items',
61
- parse: (raw) => (Array.isArray(raw) ? raw : [])
62
- });
63
- await store.reloadFromStorage();
64
- const listener = jest.fn();
65
- store.subscribe(listener);
66
- await store.set(['a']);
67
- expect(listener).not.toHaveBeenCalled();
68
- expect(storage.setMock).not.toHaveBeenCalled();
69
- });
70
- it('reloadFromStorage applies parsed storage values', async () => {
71
- const storage = createMockStorage({ count: 3 });
72
- const store = createStorageStore({
73
- storage,
74
- key: 'count',
75
- parse: (raw) => (typeof raw === 'number' ? raw : 0)
76
- });
77
- const listener = jest.fn();
78
- store.subscribe(listener);
79
- await store.reloadFromStorage();
80
- expect(store.getSnapshot()).toBe(3);
81
- expect(listener).toHaveBeenCalledTimes(1);
82
- });
83
- it('reloadFromStorage skips notify when parsed value is unchanged', async () => {
84
- const storage = createMockStorage({ count: 2 });
85
- const store = createStorageStore({
86
- storage,
87
- key: 'count',
88
- parse: (raw) => (typeof raw === 'number' ? raw : 0)
89
- });
90
- await store.reloadFromStorage();
91
- const listener = jest.fn();
92
- store.subscribe(listener);
93
- await store.reloadFromStorage();
94
- expect(listener).not.toHaveBeenCalled();
95
- });
96
- it('uses a custom equals function', async () => {
97
- const storage = createMockStorage();
98
- const store = createStorageStore({
99
- storage,
100
- key: 'status',
101
- parse: (raw) => raw && typeof raw === 'object' && 'running' in raw
102
- ? raw
103
- : { running: false },
104
- equals: (a, b) => a.running === b.running
105
- });
106
- await store.set({ running: true });
107
- const listener = jest.fn();
108
- store.subscribe(listener);
109
- storage.data.status = { running: true, port: 8080 };
110
- await store.reloadFromStorage();
111
- expect(listener).not.toHaveBeenCalled();
112
- expect(store.getSnapshot()).toEqual({ running: true });
113
- });
114
- it('keeps the current snapshot when storage is missing and keepCurrentWhenMissing is true', async () => {
115
- const storage = createMockStorage();
116
- const store = createStorageStore({
117
- storage,
118
- key: 'status',
119
- parse: () => ({ running: false }),
120
- keepCurrentWhenMissing: true
121
- });
122
- await store.set({ running: true });
123
- delete storage.data.status;
124
- const listener = jest.fn();
125
- store.subscribe(listener);
126
- await store.reloadFromStorage();
127
- expect(listener).not.toHaveBeenCalled();
128
- expect(store.getSnapshot()).toEqual({ running: true });
129
- });
130
- });
131
- describe('setIntervalDisposable', () => {
132
- beforeEach(() => {
133
- jest.useFakeTimers();
134
- });
135
- afterEach(() => {
136
- jest.useRealTimers();
137
- });
138
- it('invokes the callback on an interval until disposed', () => {
139
- const callback = jest.fn();
140
- const disposable = setIntervalDisposable(callback, 100);
141
- jest.advanceTimersByTime(250);
142
- expect(callback).toHaveBeenCalledTimes(2);
143
- disposable.dispose();
144
- jest.advanceTimersByTime(200);
145
- expect(callback).toHaveBeenCalledTimes(2);
146
- });
147
- });
148
- describe('syncOnWindowFocus', () => {
149
- const focusListeners = new Set();
150
- const visibilityListeners = new Set();
151
- const originalWindow = globalThis.window;
152
- const originalDocument = globalThis.document;
153
- beforeEach(() => {
154
- jest.useFakeTimers();
155
- focusListeners.clear();
156
- visibilityListeners.clear();
157
- globalThis.window = {
158
- addEventListener: (type, listener) => {
159
- if (type === 'focus' && typeof listener === 'function') {
160
- focusListeners.add(listener);
161
- }
162
- },
163
- removeEventListener: (type, listener) => {
164
- if (type === 'focus' && typeof listener === 'function') {
165
- focusListeners.delete(listener);
166
- }
167
- },
168
- dispatchEvent: (event) => {
169
- if (event.type === 'focus') {
170
- for (const listener of focusListeners) {
171
- listener(event);
172
- }
173
- }
174
- return true;
175
- }
176
- };
177
- globalThis.document = {
178
- addEventListener: (type, listener) => {
179
- if (type === 'visibilitychange' && typeof listener === 'function') {
180
- visibilityListeners.add(listener);
181
- }
182
- },
183
- removeEventListener: (type, listener) => {
184
- if (type === 'visibilitychange' && typeof listener === 'function') {
185
- visibilityListeners.delete(listener);
186
- }
187
- },
188
- dispatchEvent: (event) => {
189
- if (event.type === 'visibilitychange') {
190
- for (const listener of visibilityListeners) {
191
- listener(event);
192
- }
193
- }
194
- return true;
195
- }
196
- };
197
- });
198
- afterEach(() => {
199
- jest.useRealTimers();
200
- globalThis.window = originalWindow;
201
- globalThis.document = originalDocument;
202
- });
203
- it('reloads stores on focus, visibility change, mount, and interval', async () => {
204
- const storage = createMockStorage({ count: 1 });
205
- const store = createStorageStore({
206
- storage,
207
- key: 'count',
208
- parse: (raw) => (typeof raw === 'number' ? raw : 0)
209
- });
210
- const reloadSpy = jest.spyOn(store, 'reloadFromStorage');
211
- const disposable = syncOnWindowFocus(store, { intervalMs: 500 });
212
- expect(reloadSpy).toHaveBeenCalledTimes(1);
213
- storage.data.count = 2;
214
- window.dispatchEvent(new Event('focus'));
215
- expect(reloadSpy).toHaveBeenCalledTimes(2);
216
- storage.data.count = 3;
217
- document.dispatchEvent(new Event('visibilitychange'));
218
- expect(reloadSpy).toHaveBeenCalledTimes(3);
219
- storage.data.count = 4;
220
- jest.advanceTimersByTime(500);
221
- expect(reloadSpy).toHaveBeenCalledTimes(4);
222
- disposable.dispose();
223
- storage.data.count = 5;
224
- window.dispatchEvent(new Event('focus'));
225
- jest.advanceTimersByTime(500);
226
- expect(reloadSpy).toHaveBeenCalledTimes(4);
227
- await store.reloadFromStorage();
228
- expect(store.getSnapshot()).toBe(5);
229
- });
230
- it('reloads multiple stores together', async () => {
231
- const storage = createMockStorage();
232
- const first = createStorageStore({
233
- storage,
234
- key: 'first',
235
- parse: (raw) => (typeof raw === 'number' ? raw : 0)
236
- });
237
- const second = createStorageStore({
238
- storage,
239
- key: 'second',
240
- parse: (raw) => (typeof raw === 'number' ? raw : 0)
241
- });
242
- const reloadFirst = jest.spyOn(first, 'reloadFromStorage');
243
- const reloadSecond = jest.spyOn(second, 'reloadFromStorage');
244
- syncOnWindowFocus([first, second]).dispose();
245
- expect(reloadFirst).toHaveBeenCalledTimes(1);
246
- expect(reloadSecond).toHaveBeenCalledTimes(1);
247
- });
248
- });
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "jsx": "react-jsx",
7
- "jsxImportSource": "@harborclient/sdk",
8
- "strict": true,
9
- "skipLibCheck": true,
10
- "noEmit": true,
11
- "isolatedModules": true,
12
- "lib": ["ES2022", "DOM"],
13
- "types": ["react"]
14
- }
15
- }