bff-store 0.1.0 → 0.1.1

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.
@@ -39,7 +39,16 @@
39
39
  "Bash(npm publish:*)",
40
40
  "Bash(rg -rn \"jotai-state-store\" --type-list)",
41
41
  "Bash(rg -rn \"jotai-state-store\" .)",
42
- "Bash(xargs sed:*)"
42
+ "Bash(xargs sed:*)",
43
+ "Bash(npx tsx:*)",
44
+ "Bash(npm ls:*)",
45
+ "Bash(perl -e 'alarm 5; exec @ARGV' -- node debug-simple.js)",
46
+ "Bash(echo \"exit: $?\")",
47
+ "Bash([ -d node_modules/mongodb ])",
48
+ "Bash(echo \"---mongodb status: $\\([ -d node_modules/mongodb ] && echo 'INSTALLED' || echo 'NOT INSTALLED'\\)\")",
49
+ "Bash(echo \"---mongodb: $\\([ -d node_modules/mongodb ] && echo 'INSTALLED' || echo 'NOT INSTALLED'\\)\")",
50
+ "Bash(xargs kill:*)",
51
+ "Bash(npm start:*)"
43
52
  ]
44
53
  }
45
54
  }
package/README.md CHANGED
@@ -124,20 +124,49 @@ await startServer({
124
124
  如果不通过 BFF,可以直接在 Node.js 中使用存储适配器:
125
125
 
126
126
  ```typescript
127
- import { createStore } from 'bff-store';
127
+ import { createNodeStore, getDefaultStore } from 'bff-store';
128
128
  import { jsonlStorage } from 'bff-store/jsonl';
129
129
  import { mongodbStorage } from 'bff-store/mongodb';
130
130
 
131
131
  // 使用 JSONL
132
- const adapter = jsonlStorage({ dir: './sessions' });
132
+ const store = createNodeStore('entity-123', [
133
+ { key: 'theme', defaultValue: 'dark' },
134
+ { key: 'count', defaultValue: 0 },
135
+ ], {
136
+ storage: jsonlStorage({ dir: './sessions' }),
137
+ });
133
138
 
134
- // 使用 MongoDB
135
- const adapter = await mongodbStorage({
136
- url: 'mongodb://localhost:27017',
137
- database: 'myapp',
139
+ // 等待初始加载完成
140
+ await store.waitForLoad();
141
+
142
+ // 使用 jotai getDefaultStore() 读写
143
+ const jotai = getDefaultStore();
144
+ jotai.set(store.atoms.theme, 'light'); // 自动 debounce 持久化
145
+ console.log(jotai.get(store.atoms.count));
146
+
147
+ // 或使用 MongoDB
148
+ const store2 = createNodeStore('entity-456', [
149
+ { key: 'data', defaultValue: null },
150
+ ], {
151
+ storage: await mongodbStorage({
152
+ url: 'mongodb://localhost:27017',
153
+ database: 'myapp',
154
+ }),
138
155
  });
156
+ ```
157
+
158
+ ### 环境检测
139
159
 
140
- const store = createStore('entity-123', config, { storage: adapter });
160
+ ```typescript
161
+ import { isNode, isBrowser } from 'bff-store';
162
+
163
+ if (isNode()) {
164
+ // Node.js 环境
165
+ }
166
+
167
+ if (isBrowser()) {
168
+ // 浏览器环境
169
+ }
141
170
  ```
142
171
 
143
172
  ## API Endpoints (BFF Server)
@@ -213,7 +242,7 @@ Note: Storage backend is configured by the client via `remoteStorage()` options,
213
242
 
214
243
  | Export | Description | Environment |
215
244
  |--------|-------------|-------------|
216
- | `bff-store` | Main entry: createStore, useStore, memoryStorage, remoteStorage | Browser + Node.js |
245
+ | `bff-store` | Main entry: createStore, useStore, createNodeStore, isNode, isBrowser, memoryStorage, remoteStorage | Browser + Node.js |
217
246
  | `bff-store/jsonl` | JSONL storage adapter | Node.js only |
218
247
  | `bff-store/mongodb` | MongoDB storage adapter | Node.js only |
219
248
  | `bff-store/server` | BFF server (startServer, Router, etc.) | Node.js only |
package/dist/index.d.mts CHANGED
@@ -229,4 +229,45 @@ interface RemoteStorageOptions {
229
229
  */
230
230
  declare function remoteStorage(options?: RemoteStorageOptions): StorageAdapter;
231
231
 
232
- export { type AsyncStorageFactory, type AtomConfig, type AtomConfigs, type AtomType, HttpTransport, type MemoryStorageOptions, RestStorageProtocol, type Storage, type StorageAdapter, type StorageFactory, type StorageHttpProtocol, type StorageOptions, type Store, type TransportAdapter, type UseStoreReturn, createMemoryStorage, createPersistedAtom, remoteStorage as createRemoteStorage, createStorageFromTransport, createStorageWithProtocol, createStore, memoryStorage, remoteStorage, useStore };
232
+ /**
233
+ * Environment detection utilities
234
+ */
235
+ declare function isNode(): boolean;
236
+ declare function isBrowser(): boolean;
237
+
238
+ /**
239
+ * Create a store for Node.js environments.
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * import { jsonlStorage } from 'bff-store/jsonl';
244
+ * import { createNodeStore } from 'bff-store';
245
+ *
246
+ * const store = createNodeStore('entity-123', [
247
+ * { key: 'theme', defaultValue: 'dark' },
248
+ * ], {
249
+ * storage: jsonlStorage({ dir: './sessions' }),
250
+ * });
251
+ *
252
+ * await store.waitForLoad();
253
+ *
254
+ * const jotai = getDefaultStore();
255
+ * jotai.set(store.atoms.theme, 'light');
256
+ * ```
257
+ */
258
+ declare function createNodeStore(entityId: string, config: AtomConfigs, options: {
259
+ storage: StorageAdapter;
260
+ debounceMs?: number;
261
+ }): {
262
+ /** Atoms to use with getDefaultStore().get/set */
263
+ atoms: StoreAtoms;
264
+ /** Loading state atoms */
265
+ loadingAtoms: StoreLoadingAtoms;
266
+ /**
267
+ * Wait for all atoms to finish loading from storage.
268
+ * Call this after creating the store to ensure data is ready.
269
+ */
270
+ waitForLoad(): Promise<void>;
271
+ };
272
+
273
+ export { type AsyncStorageFactory, type AtomConfig, type AtomConfigs, type AtomType, HttpTransport, type MemoryStorageOptions, RestStorageProtocol, type Storage, type StorageAdapter, type StorageFactory, type StorageHttpProtocol, type StorageOptions, type Store, type TransportAdapter, type UseStoreReturn, createMemoryStorage, createNodeStore, createPersistedAtom, remoteStorage as createRemoteStorage, createStorageFromTransport, createStorageWithProtocol, createStore, isBrowser, isNode, memoryStorage, remoteStorage, useStore };
package/dist/index.d.ts CHANGED
@@ -229,4 +229,45 @@ interface RemoteStorageOptions {
229
229
  */
230
230
  declare function remoteStorage(options?: RemoteStorageOptions): StorageAdapter;
231
231
 
232
- export { type AsyncStorageFactory, type AtomConfig, type AtomConfigs, type AtomType, HttpTransport, type MemoryStorageOptions, RestStorageProtocol, type Storage, type StorageAdapter, type StorageFactory, type StorageHttpProtocol, type StorageOptions, type Store, type TransportAdapter, type UseStoreReturn, createMemoryStorage, createPersistedAtom, remoteStorage as createRemoteStorage, createStorageFromTransport, createStorageWithProtocol, createStore, memoryStorage, remoteStorage, useStore };
232
+ /**
233
+ * Environment detection utilities
234
+ */
235
+ declare function isNode(): boolean;
236
+ declare function isBrowser(): boolean;
237
+
238
+ /**
239
+ * Create a store for Node.js environments.
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * import { jsonlStorage } from 'bff-store/jsonl';
244
+ * import { createNodeStore } from 'bff-store';
245
+ *
246
+ * const store = createNodeStore('entity-123', [
247
+ * { key: 'theme', defaultValue: 'dark' },
248
+ * ], {
249
+ * storage: jsonlStorage({ dir: './sessions' }),
250
+ * });
251
+ *
252
+ * await store.waitForLoad();
253
+ *
254
+ * const jotai = getDefaultStore();
255
+ * jotai.set(store.atoms.theme, 'light');
256
+ * ```
257
+ */
258
+ declare function createNodeStore(entityId: string, config: AtomConfigs, options: {
259
+ storage: StorageAdapter;
260
+ debounceMs?: number;
261
+ }): {
262
+ /** Atoms to use with getDefaultStore().get/set */
263
+ atoms: StoreAtoms;
264
+ /** Loading state atoms */
265
+ loadingAtoms: StoreLoadingAtoms;
266
+ /**
267
+ * Wait for all atoms to finish loading from storage.
268
+ * Call this after creating the store to ensure data is ready.
269
+ */
270
+ waitForLoad(): Promise<void>;
271
+ };
272
+
273
+ export { type AsyncStorageFactory, type AtomConfig, type AtomConfigs, type AtomType, HttpTransport, type MemoryStorageOptions, RestStorageProtocol, type Storage, type StorageAdapter, type StorageFactory, type StorageHttpProtocol, type StorageOptions, type Store, type TransportAdapter, type UseStoreReturn, createMemoryStorage, createNodeStore, createPersistedAtom, remoteStorage as createRemoteStorage, createStorageFromTransport, createStorageWithProtocol, createStore, isBrowser, isNode, memoryStorage, remoteStorage, useStore };
package/dist/index.mjs CHANGED
@@ -415,15 +415,58 @@ function remoteStorage(options = {}) {
415
415
  };
416
416
  return adapter;
417
417
  }
418
+
419
+ // src/environment.ts
420
+ function isNode() {
421
+ return typeof window === "undefined" && typeof process !== "undefined";
422
+ }
423
+ function isBrowser() {
424
+ return typeof window !== "undefined";
425
+ }
426
+
427
+ // src/nodeStore.ts
428
+ import { getDefaultStore as getDefaultStore3 } from "jotai";
429
+ function createNodeStore(entityId, config, options) {
430
+ const store = createStore(entityId, config, options);
431
+ const jotaiStore = getDefaultStore3();
432
+ async function waitForLoad() {
433
+ for (const atom2 of Object.values(store.atoms)) {
434
+ jotaiStore.sub(atom2, () => {
435
+ });
436
+ }
437
+ return new Promise((resolve) => {
438
+ const loadingAtoms = Object.values(store.loadingAtoms);
439
+ const stillLoading = () => loadingAtoms.some((atom2) => jotaiStore.get(atom2));
440
+ if (!stillLoading()) {
441
+ resolve();
442
+ return;
443
+ }
444
+ const interval = setInterval(() => {
445
+ if (!stillLoading()) {
446
+ clearInterval(interval);
447
+ resolve();
448
+ }
449
+ }, 10);
450
+ });
451
+ }
452
+ return {
453
+ atoms: store.atoms,
454
+ loadingAtoms: store.loadingAtoms,
455
+ waitForLoad
456
+ };
457
+ }
418
458
  export {
419
459
  HttpTransport,
420
460
  RestStorageProtocol,
421
461
  createMemoryStorage,
462
+ createNodeStore,
422
463
  createPersistedAtom,
423
464
  remoteStorage as createRemoteStorage,
424
465
  createStorageFromTransport,
425
466
  createStorageWithProtocol,
426
467
  createStore,
468
+ isBrowser,
469
+ isNode,
427
470
  memoryStorage,
428
471
  remoteStorage,
429
472
  useStore
package/dist/package.json CHANGED
@@ -8,8 +8,7 @@
8
8
  "exports": {
9
9
  ".": {
10
10
  "types": "./index.d.ts",
11
- "import": "./index.mjs",
12
- "require": "./index.js"
11
+ "import": "./index.mjs"
13
12
  },
14
13
  "./jsonl": {
15
14
  "types": "./storage/jsonl-entry.d.ts",
@@ -50,13 +49,11 @@
50
49
  "@types/react": "^19.2.16",
51
50
  "jotai": "^2.6.0",
52
51
  "jsdom": "^29.1.1",
52
+ "mongodb": "^6.21.0",
53
53
  "react": "^18.2.0",
54
54
  "react-dom": "^18.2.0",
55
55
  "tsup": "^8.0.0",
56
56
  "typescript": "^5.0.0",
57
57
  "vitest": "^1.0.0"
58
- },
59
- "dependencies": {
60
- "mongodb": "^6.21.0"
61
58
  }
62
59
  }