localspace 0.2.2 β†’ 0.3.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.
Files changed (54) hide show
  1. package/README.md +222 -21
  2. package/dist/core/plugin-manager.d.ts +48 -0
  3. package/dist/core/plugin-manager.d.ts.map +1 -0
  4. package/dist/core/plugin-manager.js +334 -0
  5. package/dist/drivers/indexeddb.d.ts.map +1 -1
  6. package/dist/drivers/indexeddb.js +377 -297
  7. package/dist/drivers/localstorage.js +44 -45
  8. package/dist/errors.js +19 -4
  9. package/dist/index.cjs.js +1 -1
  10. package/dist/index.cjs.js.map +1 -1
  11. package/dist/index.d.ts +8 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.esm.js +1 -1
  14. package/dist/index.esm.js.map +1 -1
  15. package/dist/index.js +8 -1
  16. package/dist/index.umd.js +1 -1
  17. package/dist/index.umd.js.map +1 -1
  18. package/dist/localspace.d.ts +16 -3
  19. package/dist/localspace.d.ts.map +1 -1
  20. package/dist/localspace.js +544 -243
  21. package/dist/plugins/compression.d.ts +16 -0
  22. package/dist/plugins/compression.d.ts.map +1 -0
  23. package/dist/plugins/compression.js +66 -0
  24. package/dist/plugins/encryption.d.ts +26 -0
  25. package/dist/plugins/encryption.d.ts.map +1 -0
  26. package/dist/plugins/encryption.js +136 -0
  27. package/dist/plugins/quota.d.ts +22 -0
  28. package/dist/plugins/quota.d.ts.map +1 -0
  29. package/dist/plugins/quota.js +162 -0
  30. package/dist/plugins/sync.d.ts +16 -0
  31. package/dist/plugins/sync.d.ts.map +1 -0
  32. package/dist/plugins/sync.js +182 -0
  33. package/dist/plugins/ttl.d.ts +14 -0
  34. package/dist/plugins/ttl.d.ts.map +1 -0
  35. package/dist/plugins/ttl.js +92 -0
  36. package/dist/types.d.ts +83 -1
  37. package/dist/types.d.ts.map +1 -1
  38. package/dist/types.js +1 -1
  39. package/dist/utils/helpers.js +3 -3
  40. package/dist/utils/serializer.d.ts.map +1 -1
  41. package/dist/utils/serializer.js +33 -34
  42. package/package.json +10 -1
  43. package/src/core/plugin-manager.ts +522 -0
  44. package/src/drivers/indexeddb.ts +243 -113
  45. package/src/drivers/localstorage.ts +1 -1
  46. package/src/index.ts +25 -0
  47. package/src/localspace.ts +387 -5
  48. package/src/plugins/compression.ts +108 -0
  49. package/src/plugins/encryption.ts +254 -0
  50. package/src/plugins/quota.ts +244 -0
  51. package/src/plugins/sync.ts +267 -0
  52. package/src/plugins/ttl.ts +142 -0
  53. package/src/types.ts +136 -1
  54. package/src/utils/serializer.ts +6 -2
package/README.md CHANGED
@@ -35,6 +35,7 @@ Starting fresh let us eliminate technical debt while maintaining API compatibili
35
35
  - [Configure isolated stores for clear data boundaries](#configure-isolated-stores-for-clear-data-boundaries)
36
36
  - [Choose drivers with predictable fallbacks](#choose-drivers-with-predictable-fallbacks)
37
37
  - [Handle binary data across browsers](#handle-binary-data-across-browsers)
38
+ - [Advanced: Coalesced Writes (IndexedDB only)](#advanced-coalesced-writes-indexeddb-only)
38
39
  - [Migration Guide](#migration-guide)
39
40
  - [Note differences from localForage before upgrading](#note-differences-from-localforage-before-upgrading)
40
41
  - [Enable compatibility mode for legacy callbacks](#enable-compatibility-mode-for-legacy-callbacks)
@@ -52,25 +53,23 @@ localspace is built on a foundation designed for growth. Here's what's planned:
52
53
  - [x] Comprehensive test coverage
53
54
  - [x] Modern build pipeline (ES modules, CommonJS, UMD)
54
55
  - [x] Batch operations (`setItems()`, `getItems()`, `removeItems()`) for higher throughput
55
- - [x] Automatic write coalescing (3-10x faster rapid writes, enabled by default)
56
+ - [x] Automatic write coalescing (3-10x faster rapid writes, opt-in for IndexedDB)
56
57
  - [x] Connection pooling, transaction batching, and warmup
57
58
  - [x] **Improved error handling** - Structured error types with detailed context
58
59
 
59
60
  ### TODO
60
- - [ ] **Plugin system** - Middleware architecture for cross-cutting concerns
61
- - [ ] **Cache API driver** - Native browser caching with automatic HTTP semantics
61
+ - [x] **Plugin system** - Middleware architecture for cross-cutting concerns
62
62
  - [ ] **OPFS driver** - Origin Private File System for high-performance file storage
63
- - [ ] **Memory driver** - In-memory storage for testing and SSR
64
63
  - [ ] **Custom driver templates** - Documentation and examples for third-party drivers
65
64
  - [ ] **Node.js** - File system and SQLite adapters
66
65
  - [ ] **React Native** - AsyncStorage and SQLite drivers
67
66
  - [ ] **Electron** - Main and renderer process coordination
68
67
  - [ ] **Deno** - Native KV store integration
69
- - [ ] **TTL plugin** - Time-to-live expiration with automatic cleanup
70
- - [ ] **Encryption plugin** - Transparent encryption/decryption with Web Crypto API
71
- - [ ] **Compression plugin** - LZ-string or Brotli compression for large values
72
- - [ ] **Sync plugin** - Multi-tab synchronization with BroadcastChannel
73
- - [ ] **Quota plugin** - Automatic quota management and cleanup strategies
68
+ - [x] **TTL plugin** - Time-to-live expiration with automatic cleanup
69
+ - [x] **Encryption plugin** - Transparent encryption/decryption with Web Crypto API
70
+ - [x] **Compression plugin** - LZ-string or Brotli compression for large values
71
+ - [x] **Sync plugin** - Multi-tab synchronization with BroadcastChannel
72
+ - [x] **Quota plugin** - Automatic quota management and cleanup strategies
74
73
 
75
74
  ### πŸ“Š Community Priorities
76
75
 
@@ -124,8 +123,8 @@ localspace.getItem('user', (error, value) => {
124
123
  });
125
124
  ```
126
125
 
127
- ### πŸš€ Get automatic performance optimization (enabled by default)
128
- localspace automatically merges rapid single writes into batched transactions, giving you **3-10x performance improvement** without changing your code. This feature is enabled by default and works transparently in the background.
126
+ ### πŸš€ Opt into automatic performance optimization (coalesced writes)
127
+ localspace can merge rapid single writes into batched transactions for IndexedDB, giving you **3-10x performance improvement** under write-heavy bursts. This is opt-in so default behavior stays predictable; enable it when you know you have high write pressure.
129
128
 
130
129
  ```ts
131
130
  // Your existing code - unchanged
@@ -139,21 +138,18 @@ await Promise.all([
139
138
  // βœ… Zero code changes required
140
139
  ```
141
140
 
142
- **How it works**: When using IndexedDB, rapid writes within an 8ms window are automatically merged into a single transaction commit. This is transparent to your application and has no impact on single writes.
141
+ **How it works**: When using IndexedDB, rapid writes within an 8ms window are merged into a single transaction commit. This is transparent to your application and has no impact on single writes.
143
142
 
144
- **Want to customize or disable it?**
143
+ **Turn it on or tune it**
145
144
  ```ts
146
145
  const instance = localspace.createInstance({
147
- coalesceWrites: true, // enabled by default
146
+ coalesceWrites: true, // opt-in (default is false)
148
147
  coalesceWindowMs: 8, // 8ms window (default)
149
148
  });
150
-
151
- // Or disable if you need strict per-operation durability
152
- const strict = localspace.createInstance({
153
- coalesceWrites: false,
154
- });
155
149
  ```
156
150
 
151
+ For consistency modes, batch limits, and failure semantics, see **Advanced: Coalesced Writes** below.
152
+
157
153
  **When is this useful?**
158
154
  - Form auto-save that writes multiple fields rapidly
159
155
  - Bulk state synchronization loops
@@ -283,6 +279,208 @@ await localspace.setItem('file', file);
283
279
  const restored = await localspace.getItem<Blob>('file');
284
280
  ```
285
281
 
282
+ ## Advanced: Coalesced Writes (IndexedDB only)
283
+
284
+ localspace offers an opt-in, configurable coalesced write path to cut IndexedDB transaction count and improve throughput under heavy write bursts.
285
+
286
+ > `coalesceWrites` defaults to `false` so behavior stays predictable. Turn it on when you expect high-frequency writes.
287
+
288
+ ### Why coalesce writes?
289
+
290
+ Each IndexedDB write opens a readwrite transaction. At high frequency, transaction startup overhead becomes a bottleneck. With coalescing enabled, `setItem` and `removeItem` calls that land within a short window (default 8 ms) are merged into fewer transactions:
291
+ - Multiple writes can share one transaction.
292
+ - `coalesceMaxBatchSize` caps how many ops each flush processes.
293
+ - `coalesceReadConsistency` controls when writes resolve and when reads see them.
294
+
295
+ ### Configuration
296
+
297
+ Relevant `LocalSpaceConfig` fields:
298
+
299
+ ```ts
300
+ interface LocalSpaceConfig {
301
+ /**
302
+ * Enable coalesced writes (IndexedDB only).
303
+ * Default: false
304
+ */
305
+ coalesceWrites?: boolean;
306
+
307
+ /**
308
+ * Time window (ms) for merging writes into the same batch.
309
+ * Default: 8
310
+ */
311
+ coalesceWindowMs?: number;
312
+
313
+ /**
314
+ * Maximum operations per flush batch. Beyond this, flush immediately
315
+ * and split into multiple transactions.
316
+ * Default: undefined (no limit)
317
+ */
318
+ coalesceMaxBatchSize?: number;
319
+
320
+ /**
321
+ * When coalesceWrites is on:
322
+ * - 'strong' (default): drain pending writes before reads
323
+ * - 'eventual': reads skip draining; writes only guarantee queueing
324
+ */
325
+ coalesceReadConsistency?: 'strong' | 'eventual';
326
+ }
327
+ ```
328
+
329
+ ### Consistency modes
330
+
331
+ #### `coalesceReadConsistency: 'strong'` (default)
332
+ - Writes (`setItem` / `removeItem`): Promises resolve after the data is persisted; flush errors reject.
333
+ - Reads (`getItem`, `iterate`, batch reads): call `drainCoalescedWrites` first so you read what you just wrote.
334
+
335
+ Use this for user settings, drafts, and any flow where you need read-your-writes.
336
+
337
+ #### `coalesceReadConsistency: 'eventual'`
338
+ - Writes: queued and resolve immediately once enqueued; flush happens in the background. Errors log `console.warn('[localspace] coalesced write failed (eventual mode)', error)` but do not reject the earlier Promise.
339
+ - Reads: do not flush pending writes, so you may briefly see stale values.
340
+ - Destructive operations still force a flush to avoid dropping queued writes: `removeItems`, `clear`, `dropInstance`.
341
+
342
+ Use this for logs/analytics or workloads that can tolerate short windows of staleness in exchange for the lightest write path.
343
+
344
+ ### Bounding batch size
345
+
346
+ ```ts
347
+ const store = localspace.createInstance({
348
+ name: 'logs',
349
+ storeName: 'events',
350
+ coalesceWrites: true,
351
+ coalesceWindowMs: 8,
352
+ coalesceMaxBatchSize: 64,
353
+ coalesceReadConsistency: 'eventual',
354
+ });
355
+ ```
356
+
357
+ - When the queue reaches `coalesceMaxBatchSize`, it flushes immediately.
358
+ - Flush splits work into batches of up to 64 ops, each in its own transaction.
359
+ - `getPerformanceStats()` reports `totalWrites`, `coalescedWrites`, and `transactionsSaved` so you can see the gains.
360
+
361
+ ### Recommended recipes
362
+
363
+ 1) Default: coalescing off
364
+ ```ts
365
+ const store = localspace.createInstance({
366
+ name: 'app',
367
+ storeName: 'keyvaluepairs',
368
+ // coalesceWrites is false by default
369
+ });
370
+ ```
371
+
372
+ 2) High-frequency writes with eventual consistency
373
+ ```ts
374
+ const logStore = localspace.createInstance({
375
+ name: 'analytics',
376
+ storeName: 'events',
377
+ coalesceWrites: true,
378
+ coalesceWindowMs: 8,
379
+ coalesceMaxBatchSize: 64,
380
+ coalesceReadConsistency: 'eventual',
381
+ });
382
+ ```
383
+ - `setItem` resolves almost immediately.
384
+ - Short windows of stale reads are acceptable.
385
+ - `clear` and `dropInstance` force-flush so queued writes are not lost.
386
+
387
+ 3) Strong consistency with bounded batches
388
+ ```ts
389
+ const userStore = localspace.createInstance({
390
+ name: 'user-data',
391
+ storeName: 'kv',
392
+ coalesceWrites: true,
393
+ coalesceWindowMs: 8,
394
+ coalesceMaxBatchSize: 32,
395
+ coalesceReadConsistency: 'strong',
396
+ });
397
+ ```
398
+ - Writes resolve after persistence.
399
+ - Reads flush pending writes first.
400
+ - Batching still reduces transaction count.
401
+
402
+ ### Caveats
403
+
404
+ - Coalesced writes apply to the IndexedDB driver only; localStorage always writes per operation.
405
+ - In `eventual` mode, writes can be lost if the page closes before flush completes, and errors surface only via `console.warn`.
406
+ - For critical durability (orders, payments, irreversible state), avoid `eventual` and consider leaving `coalesceWrites` off entirely.
407
+
408
+ ## Plugin System
409
+
410
+ localspace now ships with a first-class plugin engine. Attach middleware when creating an instance or call `use()` later; plugins can mutate payloads, observe driver context, and run async interceptors around every storage call.
411
+
412
+ ```ts
413
+ const store = localspace.createInstance({
414
+ name: 'secure-store',
415
+ storeName: 'primary',
416
+ plugins: [
417
+ ttlPlugin({ defaultTTL: 60_000 }),
418
+ encryptionPlugin({ key: '0123456789abcdef0123456789abcdef' }),
419
+ compressionPlugin({ threshold: 1024 }),
420
+ syncPlugin({ channelName: 'localspace-sync' }),
421
+ quotaPlugin({ maxSize: 5 * 1024 * 1024, evictionPolicy: 'lru' }),
422
+ ],
423
+ });
424
+ ```
425
+
426
+ ### Lifecycle and hooks
427
+
428
+ - **Registration** – supply `plugins` when calling `createInstance()` or chain `instance.use(plugin)` later. Each plugin can also expose `enabled` (boolean or function) and `priority` to control execution order.
429
+ - **Lifecycle events** – `onInit(context)` is invoked after `ready()`, and `onDestroy` lets you tear down timers or channels. Call `await instance.destroy()` when disposing of an instance to run every `onDestroy` hook (executed in reverse priority order). Context exposes the active driver, db info, config, and a shared `metadata` bag for cross-plugin coordination.
430
+ - **Interceptors** – hook into `beforeSet/afterSet`, `beforeGet/afterGet`, `beforeRemove/afterRemove`, plus batch-specific methods such as `beforeSetItems` or `beforeGetItems`. Hooks run sequentially: `before*` hooks execute from highest to lowest priority, while `after*` hooks unwind in reverse order so layered transformations (compression β†’ encryption β†’ TTL) remain invertible. Returning a value passes it to the next plugin, while throwing a `LocalSpaceError` aborts the operation.
431
+ - **Per-call state** – plugins can stash data on `context.operationState` (e.g., capture the original value in `beforeSet` and reuse it in `afterSet`). For batch operations, `context.operationState.isBatch` is `true` and `context.operationState.batchSize` provides the total count.
432
+ - **Error handling & init policy** – unexpected exceptions are reported through `plugin.onError`. Throw a `LocalSpaceError` if you need to stop the pipeline (quota violations, failed decryptions, etc.). If a plugin `onInit` throws, the default policy is fail-fast (propagate and abort init). Set `pluginInitPolicy: 'disable-and-continue'` in config to log and skip the failing plugin instead (use with care for critical plugins like encryption).
433
+
434
+ ### Plugin execution order
435
+
436
+ Plugins are sorted by `priority` (higher runs first in `before*`, last in `after*`). Default priorities:
437
+
438
+ | Plugin | Priority | Notes |
439
+ |--------|----------|-------|
440
+ | sync | -100 | Runs last in `afterSet` to broadcast original (untransformed) values |
441
+ | quota | -10 | Runs late so it measures final payload sizes |
442
+ | ttl, encryption, compression | 0 | Default; chain in registration order |
443
+
444
+ **Recommended order**: `[ttlPlugin, encryptionPlugin, compressionPlugin, syncPlugin, quotaPlugin]`
445
+
446
+ ### Built-in plugins
447
+
448
+ #### TTL plugin
449
+ Wraps values as `{ data, expiresAt }`, invalidates stale reads, and optionally runs background cleanup. Options:
450
+
451
+ - `defaultTTL` (ms) and `keyTTL` overrides
452
+ - `cleanupInterval` to periodically scan `iterate()` output
453
+ - `onExpire(key, value)` callback before removal
454
+
455
+ #### Encryption plugin
456
+ Encrypts serialized payloads using the Web Crypto API (AES-GCM by default) and decrypts transparently on reads.
457
+
458
+ - Provide a `key` (CryptoKey/ArrayBuffer/string) or `keyDerivation` block (PBKDF2)
459
+ - Customize `algorithm`, `ivLength`, `ivGenerator`, or `randomSource`
460
+ - Works in browsers and modern Node runtimes (pass your own `subtle` when needed)
461
+
462
+ #### Compression plugin
463
+ Runs LZ-string compression (or a custom codec) when payloads exceed a `threshold` and restores them on read.
464
+
465
+ - `threshold` (bytes) controls when compression kicks in
466
+ - Supply a custom `{ compress, decompress }` codec if you prefer pako/Brotli
467
+
468
+ #### Sync plugin
469
+ Keeps multiple tabs/processes in sync via `BroadcastChannel` (with `storage`-event fallback).
470
+
471
+ - `channelName` separates logical buses
472
+ - `syncKeys` lets you scope which keys broadcast
473
+ - `conflictStrategy` defaults to `last-write-wins`; provide `onConflict` (return `false` to drop remote writes) for merge logic
474
+
475
+ #### Quota plugin
476
+ Tracks approximate storage usage after every mutation and enforces limits.
477
+
478
+ - `maxSize` (bytes) and optional `useNavigatorEstimate` to read the browser’s quota
479
+ - `evictionPolicy: 'error' | 'lru'` (LRU removes least-recently-used keys automatically)
480
+ - `onQuotaExceeded(info)` fires before throwing so you can log/alert users
481
+
482
+ > Tip: place quota plugins last so they see the final payload size after other transformations (TTL, encryption, compression, etc.).
483
+
286
484
  ## Migration Guide
287
485
 
288
486
  ### Note differences from localForage before upgrading
@@ -324,14 +522,15 @@ localspace.setItem('key', 'value', (err, value) => {
324
522
  ```
325
523
 
326
524
  ## Performance notes
327
- - **Automatic write coalescing (enabled by default):** localspace automatically merges rapid single writes (`setItem`/`removeItem`) within an 8ms window into one transaction, giving you 3-10x performance improvement with zero code changes. This is enabled by default for IndexedDB. Set `coalesceWrites: false` if you need strict per-operation durability.
525
+ - **Automatic write coalescing (opt-in):** localspace can merge rapid single writes (`setItem`/`removeItem`) within an 8ms window into one transaction for IndexedDB, delivering 3-10x speedups under bursty writes. Enable with `coalesceWrites: true` and see **Advanced: Coalesced Writes** for consistency modes.
526
+ - **Read-your-writes consistency with coalescing:** Pending coalesced writes are flushed before reads (`getItem`, `getItems`, `iterate`, `keys`, `length`, `key`) and destructive ops (`clear`, `dropInstance`), so immediate reads always observe the latest value. If you need eventual reads for speed, you can switch `coalesceReadConsistency` to `'eventual'`.
328
527
  - **Batch APIs outperform loops:** Playwright benchmark (`test/playwright/benchmark.spec.ts`) on 500 items x 256B showed `setItems()` ~6x faster and `getItems()` ~7.7x faster than per-item loops, with `removeItems()` ~2.8x faster (Chromium, relaxed durability).
329
528
  - **Transaction helpers:** `runTransaction()` lets you co-locate reads/writes in a single transaction for atomic migrations and to shorten lock time.
330
529
  - **Batch sizing:** Use `maxBatchSize` to split very large batch operations (`setItems`/`removeItems`/`getItems`) and keep transaction size in check. This works independently from `coalesceWrites`, which optimizes single-item operations.
331
530
  - **IndexedDB durability defaults:** Chrome 121+ uses relaxed durability by default; keep it for speed or set `durability: 'strict'` in `config` for migration-style writes.
332
531
  - **Storage Buckets (Chromium 122+):** supply a `bucket` option to isolate critical data and hint durability/persistence per bucket.
333
532
  - **Connection warmup:** IndexedDB instances pre-warm a transaction after init to reduce first-op latency (`prewarmTransactions` enabled by default; set to `false` to skip).
334
- - **Recommended defaults:** keep `coalesceWrites` enabled (default), `durability` relaxed, and `prewarmTransactions` on. Set `connectionIdleMs` only if you want idle connections to auto-close, and `maxBatchSize` only for very large bulk writes. Prefer IndexedDB for atomic/bulk writes since localStorage batches are non-atomic. Use `maxConcurrentTransactions` to throttle heavy parallel workloads when needed.
533
+ - **Recommended defaults:** leave `coalesceWrites` off unless you know you need higher write throughput; if you enable it, prefer the default `strong` consistency. Keep `durability` relaxed and `prewarmTransactions` on. Set `connectionIdleMs` only if you want idle connections to auto-close, and `maxBatchSize` only for very large bulk writes. Prefer IndexedDB for atomic/bulk writes since localStorage batches are non-atomic. Use `maxConcurrentTransactions` to throttle heavy parallel workloads when needed.
335
534
  - **localStorage batch atomicity:** When using localStorage driver, batch operations (`setItems()`, `removeItems()`) are **not atomic**. If an error occurs mid-operation, some items may be written or removed while others are not. In contrast, IndexedDB batch operations use transactions and guarantee atomicity (all-or-nothing). If atomicity is critical for your use case, prefer IndexedDB driver or implement application-level rollback logic.
336
535
 
337
536
  When `compatibilityMode` is off, driver setup methods also use Node-style callbacks. Promises are recommended for all new code.
@@ -342,6 +541,8 @@ When `compatibilityMode` is off, driver setup methods also use Node-style callba
342
541
  - **Read structured errors:** Rejections surface as `LocalSpaceError` with a `code`, contextual `details` (driver, operation, key, attemptedDrivers), and the original `cause`. Branch on `error.code` instead of parsing strings.
343
542
  - **Handle quota errors:** Check for `error.code === 'QUOTA_EXCEEDED'` (or inspect `error.cause`) from `setItem` to inform users about storage limits.
344
543
  - **Run unit tests:** The project ships with Vitest and Playwright suites covering API behavior; run `yarn test` to verify changes.
544
+ - **Collect Playwright coverage:** Run `yarn test:e2e:coverage` to re-build the bundle, execute the Playwright suite with Chromium V8 coverage enabled, and emit both text + HTML reports via `nyc` (open `coverage/index.html` after the run; raw JSON sits in `.nyc_output`).
545
+ - **Collect combined Vitest + Playwright coverage:** Run `yarn coverage:full` to clean previous artifacts, run `vitest --coverage`, stash its Istanbul JSON into `.nyc_output`, then execute the coverage-enabled Playwright suite and emit merged `nyc` reports.
345
546
 
346
547
  ## License
347
548
  [MIT](./LICENSE)
@@ -0,0 +1,48 @@
1
+ import type { BatchItems, BatchResponse, DbInfo, LocalSpaceConfig, LocalSpaceInstance, LocalSpacePlugin, PluginContext, PluginOperation } from '../types';
2
+ export declare class PluginAbortError extends Error {
3
+ constructor(message?: string);
4
+ }
5
+ type PluginHost = LocalSpaceInstance & {
6
+ _config: LocalSpaceConfig;
7
+ _dbInfo: DbInfo | null;
8
+ };
9
+ export declare class PluginManager {
10
+ private readonly host;
11
+ private readonly sharedMetadata;
12
+ private readonly pluginRegistry;
13
+ private readonly initialized;
14
+ private readonly initPromises;
15
+ private readonly destroyed;
16
+ private readonly disabled;
17
+ private orderCounter;
18
+ constructor(host: PluginHost, initialPlugins?: LocalSpacePlugin[]);
19
+ hasPlugins(): boolean;
20
+ registerPlugins(plugins: LocalSpacePlugin[]): void;
21
+ private sortPlugins;
22
+ private getActivePlugins;
23
+ ensureInitialized(): Promise<void>;
24
+ createContext(operation: PluginOperation | null): PluginContext;
25
+ beforeSet<T>(key: string, value: T, context: PluginContext): Promise<T>;
26
+ afterSet<T>(key: string, value: T, context: PluginContext): Promise<void>;
27
+ beforeGet(key: string, context: PluginContext): Promise<string>;
28
+ afterGet<T>(key: string, value: T | null, context: PluginContext): Promise<T | null>;
29
+ beforeRemove(key: string, context: PluginContext): Promise<string>;
30
+ afterRemove(key: string, context: PluginContext): Promise<void>;
31
+ beforeSetItems<T>(entries: BatchItems<T>, context: PluginContext): Promise<BatchItems<T>>;
32
+ afterSetItems<T>(entries: BatchResponse<T>, context: PluginContext): Promise<BatchResponse<T>>;
33
+ beforeGetItems(keys: string[], context: PluginContext): Promise<string[]>;
34
+ afterGetItems<T>(entries: BatchResponse<T>, context: PluginContext): Promise<BatchResponse<T>>;
35
+ beforeRemoveItems(keys: string[], context: PluginContext): Promise<string[]>;
36
+ afterRemoveItems(keys: string[], context: PluginContext): Promise<void>;
37
+ destroy(): Promise<void>;
38
+ normalizeBatch<T>(items: BatchItems<T>): Array<{
39
+ key: string;
40
+ value: T;
41
+ }>;
42
+ private shouldPropagate;
43
+ private dispatchPluginError;
44
+ private invokeValueHook;
45
+ private invokeVoidHook;
46
+ }
47
+ export {};
48
+ //# sourceMappingURL=plugin-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-manager.d.ts","sourceRoot":"","sources":["../../src/core/plugin-manager.ts"],"names":[],"mappings":"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"}