@framers/sql-storage-adapter 0.6.12 → 0.6.14

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 (74) hide show
  1. package/README.md +20 -3
  2. package/dist/adapters/baseStorageAdapter.d.ts +3 -3
  3. package/dist/adapters/betterSqliteAdapter.d.ts +1 -1
  4. package/dist/adapters/capacitorSqliteAdapter.d.ts +43 -1
  5. package/dist/adapters/capacitorSqliteAdapter.d.ts.map +1 -1
  6. package/dist/adapters/capacitorSqliteAdapter.js +139 -21
  7. package/dist/adapters/capacitorSqliteAdapter.js.map +1 -1
  8. package/dist/adapters/electron/electronMainAdapter.d.ts +1 -1
  9. package/dist/adapters/electron/electronRendererAdapter.d.ts +2 -2
  10. package/dist/adapters/electron/index.d.ts +10 -10
  11. package/dist/adapters/electron/ipc/index.d.ts +3 -3
  12. package/dist/adapters/electron/ipc/protocol.d.ts +1 -1
  13. package/dist/adapters/electron/ipc/types.d.ts +1 -1
  14. package/dist/adapters/electron/migration/autoMigrator.d.ts +1 -1
  15. package/dist/adapters/electron/migration/index.d.ts +1 -1
  16. package/dist/adapters/electron/preload.d.ts +2 -2
  17. package/dist/adapters/electron/recovery/corruptionDetector.d.ts +1 -1
  18. package/dist/adapters/electron/recovery/index.d.ts +2 -2
  19. package/dist/adapters/electron/recovery/walCheckpoint.d.ts +1 -1
  20. package/dist/adapters/electron/window/index.d.ts +1 -1
  21. package/dist/adapters/electron/window/windowManager.d.ts +1 -1
  22. package/dist/adapters/indexedDbAdapter.d.ts +90 -11
  23. package/dist/adapters/indexedDbAdapter.d.ts.map +1 -1
  24. package/dist/adapters/indexedDbAdapter.js +265 -58
  25. package/dist/adapters/indexedDbAdapter.js.map +1 -1
  26. package/dist/adapters/postgresAdapter.d.ts +1 -1
  27. package/dist/adapters/sqlJsAdapter.d.ts +1 -1
  28. package/dist/adapters/supabase.d.ts +2 -2
  29. package/dist/core/contracts/context.d.ts +2 -2
  30. package/dist/core/contracts/events.d.ts +2 -2
  31. package/dist/core/contracts/extensions.d.ts +3 -3
  32. package/dist/core/contracts/hooks.d.ts +1 -1
  33. package/dist/core/contracts/index.d.ts +2 -2
  34. package/dist/core/contracts/limitations.d.ts +1 -1
  35. package/dist/core/database.d.ts +18 -10
  36. package/dist/core/database.d.ts.map +1 -1
  37. package/dist/core/database.js +17 -8
  38. package/dist/core/database.js.map +1 -1
  39. package/dist/core/resolver.d.ts +20 -10
  40. package/dist/core/resolver.d.ts.map +1 -1
  41. package/dist/core/resolver.js +43 -7
  42. package/dist/core/resolver.js.map +1 -1
  43. package/dist/features/backup/cloudBackup.d.ts +1 -1
  44. package/dist/features/migrations/dataExport.d.ts +1 -1
  45. package/dist/features/migrations/dataImport.d.ts +2 -2
  46. package/dist/features/migrations/migration.d.ts +2 -2
  47. package/dist/features/sync/conflicts/conflictResolver.d.ts +1 -1
  48. package/dist/features/sync/conflicts/index.d.ts +1 -1
  49. package/dist/features/sync/crossPlatformSync.d.ts +6 -6
  50. package/dist/features/sync/devices/deviceManager.d.ts +2 -2
  51. package/dist/features/sync/devices/index.d.ts +1 -1
  52. package/dist/features/sync/index.d.ts +9 -9
  53. package/dist/features/sync/protocol/index.d.ts +2 -2
  54. package/dist/features/sync/protocol/messages.d.ts +1 -1
  55. package/dist/features/sync/syncManager.d.ts +1 -1
  56. package/dist/features/sync/tables/index.d.ts +1 -1
  57. package/dist/features/sync/tables/syncLogManager.d.ts +4 -4
  58. package/dist/features/sync/transport/httpTransport.d.ts +2 -2
  59. package/dist/features/sync/transport/index.d.ts +3 -3
  60. package/dist/features/sync/transport/transport.d.ts +1 -1
  61. package/dist/features/sync/transport/websocketTransport.d.ts +2 -2
  62. package/dist/index.d.ts +25 -25
  63. package/dist/shared/connectionGate.d.ts +32 -9
  64. package/dist/shared/connectionGate.d.ts.map +1 -1
  65. package/dist/shared/connectionGate.js +31 -12
  66. package/dist/shared/connectionGate.js.map +1 -1
  67. package/dist/shared/parameterUtils.d.ts +1 -1
  68. package/dist/shared/postgresTarget.d.ts +10 -0
  69. package/dist/shared/postgresTarget.d.ts.map +1 -0
  70. package/dist/shared/postgresTarget.js +13 -0
  71. package/dist/shared/postgresTarget.js.map +1 -0
  72. package/dist/shared/serializedTransaction.d.ts +1 -1
  73. package/dist/types/index.d.ts +7 -7
  74. package/package.json +2 -1
@@ -25,13 +25,13 @@
25
25
  * await sync.sync();
26
26
  * ```
27
27
  */
28
- export { CrossPlatformSync, createCrossPlatformSync, type CrossPlatformSyncOptions, type CrossPlatformSyncHooks, type TableSyncConfig, type SyncResult, type SyncStatus as CrossPlatformSyncStatus, } from './crossPlatformSync';
29
- export { VectorClock, createVectorClock, compareClocks, mergeClocks, generateDeviceId, dominates, type VectorClockData, type CausalRelation, type SerializedVectorClock, } from './protocol/vectorClock';
30
- export { type ChangeOperation, type ChangeRecord, type ChangeBatch, type SyncProgress, type SyncStatus as ProtocolSyncStatus, type BaseMessage, type HandshakeRequest, type HandshakeResponse, type DeltaPush, type DeltaPullRequest, type DeltaPullResponse, type AckMessage, type ConflictMessage, type PresenceMessage, type HeartbeatMessage, type HeartbeatAck, type ErrorMessage, type SyncMessage, type SyncMessageType, type DeviceType as ProtocolDeviceType, type DeviceInfo as ProtocolDeviceInfo, type ConflictResolution as ProtocolConflictResolution, generateMessageId, createBaseMessage, createHandshakeRequest, createAck, createHeartbeat, createError, createDeltaPushMessage, createDeltaPullRequest, createPresenceMessage, createHeartbeatMessage, createAckMessage, generateChangeId, createChangeRecord, isHandshakeRequest, isDeltaPush, isConflict, isError, isSyncMessage, } from './protocol/messages';
31
- export { BaseTransport, TransportError, TransportErrorCodes, type SyncTransport, type TransportOptions, type TransportState, type TransportStats, type TransportEventType, type TransportEvents, type TransportEventListener, } from './transport/transport';
32
- export { WebSocketTransport, createWebSocketTransport, type WebSocketTransportOptions, } from './transport/websocketTransport';
33
- export { HttpTransport, createHttpTransport, type HttpTransportOptions, } from './transport/httpTransport';
34
- export { ConflictResolver, createConflictResolver, FieldMergers, type ConflictStrategy, type ResolutionDecision, type SyncConflict, type ConflictResolution, type ConflictUIHooks, type ConflictResolverOptions, type FieldMerger, } from './conflicts/conflictResolver';
35
- export { DeviceManager, createDeviceManager, type DeviceType, type PresenceStatus, type DeviceInfo, type DeviceCapabilities, type DeviceRegistrationOptions, type PresenceEvent, type DeviceManagerEventType, type DeviceManagerEvents, type DeviceManagerOptions, } from './devices/deviceManager';
36
- export { SyncLogManager, type ChangeLogEntry as SyncLogChange, type ConflictEntry as SyncLogConflict, } from './tables/syncLogManager';
28
+ export { CrossPlatformSync, createCrossPlatformSync, type CrossPlatformSyncOptions, type CrossPlatformSyncHooks, type TableSyncConfig, type SyncResult, type SyncStatus as CrossPlatformSyncStatus, } from './crossPlatformSync.js';
29
+ export { VectorClock, createVectorClock, compareClocks, mergeClocks, generateDeviceId, dominates, type VectorClockData, type CausalRelation, type SerializedVectorClock, } from './protocol/vectorClock.js';
30
+ export { type ChangeOperation, type ChangeRecord, type ChangeBatch, type SyncProgress, type SyncStatus as ProtocolSyncStatus, type BaseMessage, type HandshakeRequest, type HandshakeResponse, type DeltaPush, type DeltaPullRequest, type DeltaPullResponse, type AckMessage, type ConflictMessage, type PresenceMessage, type HeartbeatMessage, type HeartbeatAck, type ErrorMessage, type SyncMessage, type SyncMessageType, type DeviceType as ProtocolDeviceType, type DeviceInfo as ProtocolDeviceInfo, type ConflictResolution as ProtocolConflictResolution, generateMessageId, createBaseMessage, createHandshakeRequest, createAck, createHeartbeat, createError, createDeltaPushMessage, createDeltaPullRequest, createPresenceMessage, createHeartbeatMessage, createAckMessage, generateChangeId, createChangeRecord, isHandshakeRequest, isDeltaPush, isConflict, isError, isSyncMessage, } from './protocol/messages.js';
31
+ export { BaseTransport, TransportError, TransportErrorCodes, type SyncTransport, type TransportOptions, type TransportState, type TransportStats, type TransportEventType, type TransportEvents, type TransportEventListener, } from './transport/transport.js';
32
+ export { WebSocketTransport, createWebSocketTransport, type WebSocketTransportOptions, } from './transport/websocketTransport.js';
33
+ export { HttpTransport, createHttpTransport, type HttpTransportOptions, } from './transport/httpTransport.js';
34
+ export { ConflictResolver, createConflictResolver, FieldMergers, type ConflictStrategy, type ResolutionDecision, type SyncConflict, type ConflictResolution, type ConflictUIHooks, type ConflictResolverOptions, type FieldMerger, } from './conflicts/conflictResolver.js';
35
+ export { DeviceManager, createDeviceManager, type DeviceType, type PresenceStatus, type DeviceInfo, type DeviceCapabilities, type DeviceRegistrationOptions, type PresenceEvent, type DeviceManagerEventType, type DeviceManagerEvents, type DeviceManagerOptions, } from './devices/deviceManager.js';
36
+ export { SyncLogManager, type ChangeLogEntry as SyncLogChange, type ConflictEntry as SyncLogConflict, } from './tables/syncLogManager.js';
37
37
  //# sourceMappingURL=index.d.ts.map
@@ -6,6 +6,6 @@
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
- export * from './vectorClock';
10
- export * from './messages';
9
+ export * from './vectorClock.js';
10
+ export * from './messages.js';
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
- import type { VectorClockData } from './vectorClock';
9
+ import type { VectorClockData } from './vectorClock.js';
10
10
  /**
11
11
  * Type of device in the sync network.
12
12
  */
@@ -33,7 +33,7 @@
33
33
  * await manager.sync();
34
34
  * ```
35
35
  */
36
- import type { StorageAdapter } from '../../core/contracts';
36
+ import type { StorageAdapter } from '../../core/contracts/index.js';
37
37
  /**
38
38
  * Sync mode determines when synchronization occurs.
39
39
  */
@@ -6,5 +6,5 @@
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
- export * from './syncLogManager';
9
+ export * from './syncLogManager.js';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -22,10 +22,10 @@
22
22
  * const changes = await syncLog.getChangesSince(remoteVectorClock);
23
23
  * ```
24
24
  */
25
- import type { StorageAdapter } from '../../../core/contracts';
26
- import type { VectorClockData } from '../protocol/vectorClock';
27
- import { VectorClock } from '../protocol/vectorClock';
28
- import type { ChangeRecord, ChangeOperation, DeviceInfo, DeviceType } from '../protocol/messages';
25
+ import type { StorageAdapter } from '../../../core/contracts/index.js';
26
+ import type { VectorClockData } from '../protocol/vectorClock.js';
27
+ import { VectorClock } from '../protocol/vectorClock.js';
28
+ import type { ChangeRecord, ChangeOperation, DeviceInfo, DeviceType } from '../protocol/messages.js';
29
29
  /**
30
30
  * Change log entry as stored in database.
31
31
  */
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
- import { BaseTransport, type TransportOptions } from './transport';
10
- import type { SyncMessage } from '../protocol/messages';
9
+ import { BaseTransport, type TransportOptions } from './transport.js';
10
+ import type { SyncMessage } from '../protocol/messages.js';
11
11
  /**
12
12
  * HTTP-specific transport options.
13
13
  */
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
- export * from './transport';
10
- export * from './websocketTransport';
11
- export * from './httpTransport';
9
+ export * from './transport.js';
10
+ export * from './websocketTransport.js';
11
+ export * from './httpTransport.js';
12
12
  //# sourceMappingURL=index.d.ts.map
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
- import type { SyncMessage } from '../protocol/messages';
9
+ import type { SyncMessage } from '../protocol/messages.js';
10
10
  /**
11
11
  * Transport connection state.
12
12
  */
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
- import { BaseTransport, type TransportOptions } from './transport';
10
- import type { SyncMessage } from '../protocol/messages';
9
+ import { BaseTransport, type TransportOptions } from './transport.js';
10
+ import type { SyncMessage } from '../protocol/messages.js';
11
11
  /**
12
12
  * WebSocket-specific transport options.
13
13
  */
package/dist/index.d.ts CHANGED
@@ -1,26 +1,26 @@
1
- export * from './types';
2
- export * from './core/database';
3
- export * from './core/resolver';
4
- export * from './adapters/betterSqliteAdapter';
5
- export * from './adapters/sqlJsAdapter';
6
- export * from './adapters/indexedDbAdapter';
7
- export * from './adapters/capacitorSqliteAdapter';
8
- export * from './adapters/postgresAdapter';
9
- export * from './adapters/supabase';
10
- export * from './adapters/baseStorageAdapter';
11
- export * from './features/backup/cloudBackup';
12
- export * from './features/migrations/dataExport';
13
- export * from './features/migrations/dataImport';
14
- export * from './features/migrations/migration';
15
- export * from './features/sync/syncManager';
16
- export * from './shared/parameterUtils';
17
- export { SqliteDialect } from './dialects/SqliteDialect';
18
- export { PostgresDialect } from './dialects/PostgresDialect';
19
- export { SqliteFts5 } from './fts/SqliteFts5';
20
- export { PostgresFts } from './fts/PostgresFts';
21
- export { NodeBlobCodec } from './codecs/NodeBlobCodec';
22
- export { BrowserBlobCodec } from './codecs/BrowserBlobCodec';
23
- export { SqliteFileExporter } from './exporters/SqliteFileExporter';
24
- export { PostgresExporter } from './exporters/PostgresExporter';
25
- export { createStorageFeatures } from './core/contracts/features';
1
+ export * from './types/index.js';
2
+ export * from './core/database.js';
3
+ export * from './core/resolver.js';
4
+ export * from './adapters/betterSqliteAdapter.js';
5
+ export * from './adapters/sqlJsAdapter.js';
6
+ export * from './adapters/indexedDbAdapter.js';
7
+ export * from './adapters/capacitorSqliteAdapter.js';
8
+ export * from './adapters/postgresAdapter.js';
9
+ export * from './adapters/supabase.js';
10
+ export * from './adapters/baseStorageAdapter.js';
11
+ export * from './features/backup/cloudBackup.js';
12
+ export * from './features/migrations/dataExport.js';
13
+ export * from './features/migrations/dataImport.js';
14
+ export * from './features/migrations/migration.js';
15
+ export * from './features/sync/syncManager.js';
16
+ export * from './shared/parameterUtils.js';
17
+ export { SqliteDialect } from './dialects/SqliteDialect.js';
18
+ export { PostgresDialect } from './dialects/PostgresDialect.js';
19
+ export { SqliteFts5 } from './fts/SqliteFts5.js';
20
+ export { PostgresFts } from './fts/PostgresFts.js';
21
+ export { NodeBlobCodec } from './codecs/NodeBlobCodec.js';
22
+ export { BrowserBlobCodec } from './codecs/BrowserBlobCodec.js';
23
+ export { SqliteFileExporter } from './exporters/SqliteFileExporter.js';
24
+ export { PostgresExporter } from './exporters/PostgresExporter.js';
25
+ export { createStorageFeatures } from './core/contracts/features.js';
26
26
  //# sourceMappingURL=index.d.ts.map
@@ -12,9 +12,11 @@
12
12
  * callback's handle it carries the transaction's token, so it is admitted
13
13
  * whatever async context runs it. Through the adapter itself, from code the
14
14
  * callback runs, the callback's async context tells it apart, so the gate needs
15
- * a context store (Node's AsyncLocalStorage); without one it admits every
16
- * statement that carries no token at once, which is how the adapters behaved
17
- * before the gate.
15
+ * a context store (Node's AsyncLocalStorage). Without one, the gate either
16
+ * admits every statement that carries no token at once, which is how the
17
+ * adapters behaved before the gate, or makes it wait like any outside caller,
18
+ * so that the handle is the only way into an open transaction: the adapters
19
+ * that run in a browser or a WebView, where there is no context store, wait.
18
20
  *
19
21
  * This module imports nothing from Node, so browser bundles can include it;
20
22
  * the adapter that runs on Node passes the store in.
@@ -50,22 +52,43 @@ export interface ConnectionGate {
50
52
  /** Releases the context store when the connection closes. */
51
53
  dispose(): void;
52
54
  }
55
+ /** How a gate treats a statement that carries no token. */
56
+ export interface ConnectionGateOptions {
57
+ /**
58
+ * When there is no context store: 'admit' runs such a statement at once (the
59
+ * default, how the adapters behaved before the gate); 'wait' holds it until
60
+ * the open transaction ends, so only the transaction's handle reaches it.
61
+ */
62
+ withoutContext?: 'admit' | 'wait';
63
+ }
53
64
  /**
54
65
  * Creates the gate of one shared connection.
55
66
  *
56
- * @param context - Node's AsyncLocalStorage, or null where there is none (the
57
- * gate then admits every statement at once).
67
+ * @param context - Node's AsyncLocalStorage, or null where there is none.
68
+ * @param options - What the gate does with a token-less statement when there
69
+ * is no context store.
58
70
  */
59
- export declare const createConnectionGate: (context: TransactionContextStore | null) => ConnectionGate;
71
+ export declare const createConnectionGate: (context: TransactionContextStore | null, options?: ConnectionGateOptions) => ConnectionGate;
72
+ /** Reports a statement that is still waiting for an open transaction after a while. */
73
+ export interface LongWaitWatch {
74
+ /** How long a statement may wait before `onLongWait` is called. */
75
+ afterMs: number;
76
+ /** Called once per waiting statement that passes `afterMs`. */
77
+ onLongWait: () => void;
78
+ }
60
79
  /**
61
- * Runs `work`, a synchronous statement, once the gate admits it. The last check
62
- * and the work happen in the same turn, so no transaction can open between
80
+ * Runs `work` once the gate admits it. `work` starts the statement: it runs it
81
+ * (a synchronous adapter) or sends it (an asynchronous one), and the last check
82
+ * and that start happen in the same turn, so no transaction can open between
63
83
  * them; a caller woken when a transaction ends checks again, since the next
64
84
  * transaction may already be open.
65
85
  *
66
86
  * @param token - The transaction's token when the statement comes through a
67
87
  * transaction handle; a handle whose transaction has ended waits like any
68
88
  * outside caller.
89
+ * @param watch - Reports a statement that waits long, which is how a callback
90
+ * that issues a statement through the adapter instead of its handle shows
91
+ * on an adapter whose gate makes such statements wait.
69
92
  */
70
- export declare const whenAdmitted: <T>(gate: ConnectionGate, work: () => T, token?: symbol) => Promise<T>;
93
+ export declare const whenAdmitted: <T>(gate: ConnectionGate, work: () => T | PromiseLike<T>, token?: symbol, watch?: LongWaitWatch) => Promise<T>;
71
94
  //# sourceMappingURL=connectionGate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connectionGate.d.ts","sourceRoot":"","sources":["../../src/shared/connectionGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,uBAAuB;IACtC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5C,QAAQ,IAAI,MAAM,GAAG,SAAS,CAAC;IAC/B,0EAA0E;IAC1E,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,qEAAqE;IACrE,MAAM,IAAI,OAAO,CAAC;IAClB,yFAAyF;IACzF,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,yEAAyE;IACzE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB;;;;;OAKG;IACH,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzD,6DAA6D;IAC7D,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,YAAa,uBAAuB,GAAG,IAAI,KAAG,cA8B9E,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAU,CAAC,QAAQ,cAAc,QAAQ,MAAM,CAAC,UAAU,MAAM,KAAG,OAAO,CAAC,CAAC,CAKpG,CAAC"}
1
+ {"version":3,"file":"connectionGate.d.ts","sourceRoot":"","sources":["../../src/shared/connectionGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,uBAAuB;IACtC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5C,QAAQ,IAAI,MAAM,GAAG,SAAS,CAAC;IAC/B,0EAA0E;IAC1E,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,qEAAqE;IACrE,MAAM,IAAI,OAAO,CAAC;IAClB,yFAAyF;IACzF,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,yEAAyE;IACzE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB;;;;;OAKG;IACH,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzD,6DAA6D;IAC7D,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,2DAA2D;AAC3D,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACnC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,YACtB,uBAAuB,GAAG,IAAI,YAC9B,qBAAqB,KAC7B,cAgCF,CAAC;AAEF,uFAAuF;AACvF,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,GAAU,CAAC,QAC5B,cAAc,QACd,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,UACtB,MAAM,UACN,aAAa,KACpB,OAAO,CAAC,CAAC,CAYX,CAAC"}
@@ -12,9 +12,11 @@
12
12
  * callback's handle it carries the transaction's token, so it is admitted
13
13
  * whatever async context runs it. Through the adapter itself, from code the
14
14
  * callback runs, the callback's async context tells it apart, so the gate needs
15
- * a context store (Node's AsyncLocalStorage); without one it admits every
16
- * statement that carries no token at once, which is how the adapters behaved
17
- * before the gate.
15
+ * a context store (Node's AsyncLocalStorage). Without one, the gate either
16
+ * admits every statement that carries no token at once, which is how the
17
+ * adapters behaved before the gate, or makes it wait like any outside caller,
18
+ * so that the handle is the only way into an open transaction: the adapters
19
+ * that run in a browser or a WebView, where there is no context store, wait.
18
20
  *
19
21
  * This module imports nothing from Node, so browser bundles can include it;
20
22
  * the adapter that runs on Node passes the store in.
@@ -22,18 +24,22 @@
22
24
  /**
23
25
  * Creates the gate of one shared connection.
24
26
  *
25
- * @param context - Node's AsyncLocalStorage, or null where there is none (the
26
- * gate then admits every statement at once).
27
+ * @param context - Node's AsyncLocalStorage, or null where there is none.
28
+ * @param options - What the gate does with a token-less statement when there
29
+ * is no context store.
27
30
  */
28
- export const createConnectionGate = (context) => {
31
+ export const createConnectionGate = (context, options = {}) => {
29
32
  let open = null;
33
+ const waitWithoutContext = options.withoutContext === 'wait';
30
34
  return {
31
35
  blocks: (token) => {
32
36
  if (open === null)
33
37
  return false;
34
38
  if (token !== undefined)
35
39
  return token !== open.id;
36
- return context !== null && context.getStore() !== open.id;
40
+ if (context === null)
41
+ return waitWithoutContext;
42
+ return context.getStore() !== open.id;
37
43
  },
38
44
  inside: () => open !== null && context !== null && context.getStore() === open.id,
39
45
  openToken: () => open?.id ?? null,
@@ -59,18 +65,31 @@ export const createConnectionGate = (context) => {
59
65
  };
60
66
  };
61
67
  /**
62
- * Runs `work`, a synchronous statement, once the gate admits it. The last check
63
- * and the work happen in the same turn, so no transaction can open between
68
+ * Runs `work` once the gate admits it. `work` starts the statement: it runs it
69
+ * (a synchronous adapter) or sends it (an asynchronous one), and the last check
70
+ * and that start happen in the same turn, so no transaction can open between
64
71
  * them; a caller woken when a transaction ends checks again, since the next
65
72
  * transaction may already be open.
66
73
  *
67
74
  * @param token - The transaction's token when the statement comes through a
68
75
  * transaction handle; a handle whose transaction has ended waits like any
69
76
  * outside caller.
77
+ * @param watch - Reports a statement that waits long, which is how a callback
78
+ * that issues a statement through the adapter instead of its handle shows
79
+ * on an adapter whose gate makes such statements wait.
70
80
  */
71
- export const whenAdmitted = async (gate, work, token) => {
72
- while (gate.blocks(token)) {
73
- await gate.ended();
81
+ export const whenAdmitted = async (gate, work, token, watch) => {
82
+ if (gate.blocks(token)) {
83
+ const timer = watch ? setTimeout(watch.onLongWait, watch.afterMs) : undefined;
84
+ try {
85
+ while (gate.blocks(token)) {
86
+ await gate.ended();
87
+ }
88
+ }
89
+ finally {
90
+ if (timer !== undefined)
91
+ clearTimeout(timer);
92
+ }
74
93
  }
75
94
  return work();
76
95
  };
@@ -1 +1 @@
1
- {"version":3,"file":"connectionGate.js","sourceRoot":"","sources":["../../src/shared/connectionGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAmCH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,OAAuC,EAAkB,EAAE;IAC9F,IAAI,IAAI,GAA+C,IAAI,CAAC;IAE5D,OAAO;QACL,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChB,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YAChC,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,KAAK,KAAK,IAAI,CAAC,EAAE,CAAC;YAClD,OAAO,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC5D,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,EAAE;QACjF,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI;QACjC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE;QAC5C,KAAK,CAAC,IAAI,CAAI,IAAmC;YAC/C,MAAM,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;YACjC,IAAI,OAAoB,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACzC,OAAO,GAAG,OAAO,CAAC;YACpB,CAAC,CAAC,CAAC;YACH,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACtE,CAAC;oBAAS,CAAC;gBACT,IAAI,GAAG,IAAI,CAAC;gBACZ,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAK,IAAoB,EAAE,IAAa,EAAE,KAAc,EAAc,EAAE;IACvG,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IACD,OAAO,IAAI,EAAE,CAAC;AAChB,CAAC,CAAC"}
1
+ {"version":3,"file":"connectionGate.js","sourceRoot":"","sources":["../../src/shared/connectionGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AA6CH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,OAAuC,EACvC,UAAiC,EAAE,EACnB,EAAE;IAClB,IAAI,IAAI,GAA+C,IAAI,CAAC;IAC5D,MAAM,kBAAkB,GAAG,OAAO,CAAC,cAAc,KAAK,MAAM,CAAC;IAE7D,OAAO;QACL,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChB,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YAChC,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,KAAK,KAAK,IAAI,CAAC,EAAE,CAAC;YAClD,IAAI,OAAO,KAAK,IAAI;gBAAE,OAAO,kBAAkB,CAAC;YAChD,OAAO,OAAO,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACxC,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,EAAE;QACjF,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI;QACjC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE;QAC5C,KAAK,CAAC,IAAI,CAAI,IAAmC;YAC/C,MAAM,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;YACjC,IAAI,OAAoB,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACzC,OAAO,GAAG,OAAO,CAAC;YACpB,CAAC,CAAC,CAAC;YACH,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACtE,CAAC;oBAAS,CAAC;gBACT,IAAI,GAAG,IAAI,CAAC;gBACZ,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAUF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,IAAoB,EACpB,IAA8B,EAC9B,KAAc,EACd,KAAqB,EACT,EAAE;IACd,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9E,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK,KAAK,SAAS;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,EAAE,CAAC;AAChB,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { StorageParameters } from '../core/contracts';
1
+ import type { StorageParameters } from '../core/contracts/index.js';
2
2
  /**
3
3
  * Normalises parameter payloads into a tuple of named/object parameters and positional arrays.
4
4
  */
@@ -0,0 +1,10 @@
1
+ import type { PostgresAdapterOptions } from '../adapters/postgresAdapter.js';
2
+ /** A string with something in it. */
3
+ export declare const isNonEmpty: (value: unknown) => value is string;
4
+ /**
5
+ * Whether Postgres options name a server: a connection string, or a host,
6
+ * database or user. `{ connectionString: process.env.DATABASE_URL }` with
7
+ * DATABASE_URL unset names none.
8
+ */
9
+ export declare const namesPostgresServer: (options: PostgresAdapterOptions | undefined) => boolean;
10
+ //# sourceMappingURL=postgresTarget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgresTarget.d.ts","sourceRoot":"","sources":["../../src/shared/postgresTarget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,qCAAqC;AACrC,eAAO,MAAM,UAAU,UAAW,OAAO,KAAG,KAAK,IAAI,MAAuD,CAAC;AAE7G;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,YAAa,sBAAsB,GAAG,SAAS,KAAG,OAO/E,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** A string with something in it. */
2
+ export const isNonEmpty = (value) => typeof value === 'string' && value.length > 0;
3
+ /**
4
+ * Whether Postgres options name a server: a connection string, or a host,
5
+ * database or user. `{ connectionString: process.env.DATABASE_URL }` with
6
+ * DATABASE_URL unset names none.
7
+ */
8
+ export const namesPostgresServer = (options) => Boolean(options &&
9
+ (isNonEmpty(options.connectionString) ||
10
+ isNonEmpty(options.host) ||
11
+ isNonEmpty(options.database) ||
12
+ isNonEmpty(options.user)));
13
+ //# sourceMappingURL=postgresTarget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgresTarget.js","sourceRoot":"","sources":["../../src/shared/postgresTarget.ts"],"names":[],"mappings":"AAEA,qCAAqC;AACrC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAc,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAE7G;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAA2C,EAAW,EAAE,CAC1F,OAAO,CACL,OAAO;IACL,CAAC,UAAU,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACnC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;QACxB,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC5B,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAC9B,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { StorageAdapter } from '../core/contracts';
1
+ import type { StorageAdapter } from '../core/contracts/index.js';
2
2
  /** Function that runs one asynchronous operation after earlier operations finish. */
3
3
  export type SerializedTransactionRunner = <T>(operation: () => Promise<T>) => Promise<T>;
4
4
  /**
@@ -19,11 +19,11 @@
19
19
  * } from '@framers/sql-storage-adapter/types';
20
20
  * ```
21
21
  */
22
- export * from '../core/contracts';
23
- export * from '../core/contracts/context';
24
- export * from '../core/contracts/events';
25
- export * from '../core/contracts/extensions';
26
- export * from '../core/contracts/limitations';
27
- export * from '../core/contracts/performance';
28
- export * from '../core/contracts/hooks';
22
+ export * from '../core/contracts/index.js';
23
+ export * from '../core/contracts/context.js';
24
+ export * from '../core/contracts/events.js';
25
+ export * from '../core/contracts/extensions.js';
26
+ export * from '../core/contracts/limitations.js';
27
+ export * from '../core/contracts/performance.js';
28
+ export * from '../core/contracts/hooks.js';
29
29
  //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@framers/sql-storage-adapter",
3
- "version": "0.6.12",
3
+ "version": "0.6.14",
4
4
  "description": "Robust cross-platform SQL storage abstraction with automatic fallbacks and runtime detection",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -111,6 +111,7 @@
111
111
  "@vitest/coverage-v8": "^3.2.7",
112
112
  "eslint": "^9.13.0",
113
113
  "eslint-config-prettier": "^9.1.0",
114
+ "fake-indexeddb": "^6.2.5",
114
115
  "patch-package": "^8.0.0",
115
116
  "rimraf": "^5.0.7",
116
117
  "semantic-release": "^24.1.0",