@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.
- package/README.md +20 -3
- package/dist/adapters/baseStorageAdapter.d.ts +3 -3
- package/dist/adapters/betterSqliteAdapter.d.ts +1 -1
- package/dist/adapters/capacitorSqliteAdapter.d.ts +43 -1
- package/dist/adapters/capacitorSqliteAdapter.d.ts.map +1 -1
- package/dist/adapters/capacitorSqliteAdapter.js +139 -21
- package/dist/adapters/capacitorSqliteAdapter.js.map +1 -1
- package/dist/adapters/electron/electronMainAdapter.d.ts +1 -1
- package/dist/adapters/electron/electronRendererAdapter.d.ts +2 -2
- package/dist/adapters/electron/index.d.ts +10 -10
- package/dist/adapters/electron/ipc/index.d.ts +3 -3
- package/dist/adapters/electron/ipc/protocol.d.ts +1 -1
- package/dist/adapters/electron/ipc/types.d.ts +1 -1
- package/dist/adapters/electron/migration/autoMigrator.d.ts +1 -1
- package/dist/adapters/electron/migration/index.d.ts +1 -1
- package/dist/adapters/electron/preload.d.ts +2 -2
- package/dist/adapters/electron/recovery/corruptionDetector.d.ts +1 -1
- package/dist/adapters/electron/recovery/index.d.ts +2 -2
- package/dist/adapters/electron/recovery/walCheckpoint.d.ts +1 -1
- package/dist/adapters/electron/window/index.d.ts +1 -1
- package/dist/adapters/electron/window/windowManager.d.ts +1 -1
- package/dist/adapters/indexedDbAdapter.d.ts +90 -11
- package/dist/adapters/indexedDbAdapter.d.ts.map +1 -1
- package/dist/adapters/indexedDbAdapter.js +265 -58
- package/dist/adapters/indexedDbAdapter.js.map +1 -1
- package/dist/adapters/postgresAdapter.d.ts +1 -1
- package/dist/adapters/sqlJsAdapter.d.ts +1 -1
- package/dist/adapters/supabase.d.ts +2 -2
- package/dist/core/contracts/context.d.ts +2 -2
- package/dist/core/contracts/events.d.ts +2 -2
- package/dist/core/contracts/extensions.d.ts +3 -3
- package/dist/core/contracts/hooks.d.ts +1 -1
- package/dist/core/contracts/index.d.ts +2 -2
- package/dist/core/contracts/limitations.d.ts +1 -1
- package/dist/core/database.d.ts +18 -10
- package/dist/core/database.d.ts.map +1 -1
- package/dist/core/database.js +17 -8
- package/dist/core/database.js.map +1 -1
- package/dist/core/resolver.d.ts +20 -10
- package/dist/core/resolver.d.ts.map +1 -1
- package/dist/core/resolver.js +43 -7
- package/dist/core/resolver.js.map +1 -1
- package/dist/features/backup/cloudBackup.d.ts +1 -1
- package/dist/features/migrations/dataExport.d.ts +1 -1
- package/dist/features/migrations/dataImport.d.ts +2 -2
- package/dist/features/migrations/migration.d.ts +2 -2
- package/dist/features/sync/conflicts/conflictResolver.d.ts +1 -1
- package/dist/features/sync/conflicts/index.d.ts +1 -1
- package/dist/features/sync/crossPlatformSync.d.ts +6 -6
- package/dist/features/sync/devices/deviceManager.d.ts +2 -2
- package/dist/features/sync/devices/index.d.ts +1 -1
- package/dist/features/sync/index.d.ts +9 -9
- package/dist/features/sync/protocol/index.d.ts +2 -2
- package/dist/features/sync/protocol/messages.d.ts +1 -1
- package/dist/features/sync/syncManager.d.ts +1 -1
- package/dist/features/sync/tables/index.d.ts +1 -1
- package/dist/features/sync/tables/syncLogManager.d.ts +4 -4
- package/dist/features/sync/transport/httpTransport.d.ts +2 -2
- package/dist/features/sync/transport/index.d.ts +3 -3
- package/dist/features/sync/transport/transport.d.ts +1 -1
- package/dist/features/sync/transport/websocketTransport.d.ts +2 -2
- package/dist/index.d.ts +25 -25
- package/dist/shared/connectionGate.d.ts +32 -9
- package/dist/shared/connectionGate.d.ts.map +1 -1
- package/dist/shared/connectionGate.js +31 -12
- package/dist/shared/connectionGate.js.map +1 -1
- package/dist/shared/parameterUtils.d.ts +1 -1
- package/dist/shared/postgresTarget.d.ts +10 -0
- package/dist/shared/postgresTarget.d.ts.map +1 -0
- package/dist/shared/postgresTarget.js +13 -0
- package/dist/shared/postgresTarget.js.map +1 -0
- package/dist/shared/serializedTransaction.d.ts +1 -1
- package/dist/types/index.d.ts +7 -7
- 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
|
|
@@ -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,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)
|
|
16
|
-
* statement that carries no token at once, which is how the
|
|
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
|
|
57
|
-
*
|
|
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
|
|
62
|
-
*
|
|
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
|
|
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
|
|
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)
|
|
16
|
-
* statement that carries no token at once, which is how the
|
|
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
|
|
26
|
-
*
|
|
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
|
-
|
|
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
|
|
63
|
-
*
|
|
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
|
-
|
|
73
|
-
|
|
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
|
|
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"}
|
|
@@ -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
|
/**
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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.
|
|
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",
|