interaqt 1.1.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent/agentspace/knowledge/generator/api-reference.md +19 -21
- package/agent/agentspace/knowledge/generator/computation-implementation.md +6 -0
- package/agent/agentspace/knowledge/generator/integration-implementation-handler.md +2 -0
- package/agent/agentspace/knowledge/usage/04-reactive-computations.md +8 -0
- package/agent/agentspace/knowledge/usage/05-interactions.md +13 -0
- package/agent/agentspace/knowledge/usage/10-async-computations.md +13 -0
- package/agent/agentspace/knowledge/usage/13-testing.md +12 -2
- package/agent/agentspace/knowledge/usage/14-api-reference.md +10 -0
- package/agent/agentspace/knowledge/usage/18-api-exports-reference.md +6 -1
- package/agent/agentspace/knowledge/usage/20-postgresql-concurrency-migration.md +105 -0
- package/agent/agentspace/knowledge/usage/README.md +1 -0
- package/dist/core/Custom.d.ts +18 -0
- package/dist/core/Custom.d.ts.map +1 -1
- package/dist/core/EventSource.d.ts +17 -0
- package/dist/core/EventSource.d.ts.map +1 -1
- package/dist/drivers/PGLite.d.ts +2 -0
- package/dist/drivers/PGLite.d.ts.map +1 -1
- package/dist/drivers/PostgreSQL.d.ts +27 -5
- package/dist/drivers/PostgreSQL.d.ts.map +1 -1
- package/dist/drivers/SQLite.d.ts +2 -0
- package/dist/drivers/SQLite.d.ts.map +1 -1
- package/dist/index.js +3651 -3042
- package/dist/index.js.map +1 -1
- package/dist/runtime/ComputationSourceMap.d.ts.map +1 -1
- package/dist/runtime/Controller.d.ts +1 -0
- package/dist/runtime/Controller.d.ts.map +1 -1
- package/dist/runtime/MonoSystem.d.ts +2 -0
- package/dist/runtime/MonoSystem.d.ts.map +1 -1
- package/dist/runtime/Scheduler.d.ts +14 -1
- package/dist/runtime/Scheduler.d.ts.map +1 -1
- package/dist/runtime/System.d.ts +40 -6
- package/dist/runtime/System.d.ts.map +1 -1
- package/dist/runtime/computations/Any.d.ts.map +1 -1
- package/dist/runtime/computations/Average.d.ts +2 -2
- package/dist/runtime/computations/Average.d.ts.map +1 -1
- package/dist/runtime/computations/Computation.d.ts +17 -0
- package/dist/runtime/computations/Computation.d.ts.map +1 -1
- package/dist/runtime/computations/Count.d.ts +5 -1
- package/dist/runtime/computations/Count.d.ts.map +1 -1
- package/dist/runtime/computations/Every.d.ts +1 -2
- package/dist/runtime/computations/Every.d.ts.map +1 -1
- package/dist/runtime/computations/StateMachine.d.ts.map +1 -1
- package/dist/runtime/computations/Summation.d.ts +3 -1
- package/dist/runtime/computations/Summation.d.ts.map +1 -1
- package/dist/runtime/computations/Transform.d.ts.map +1 -1
- package/dist/runtime/computations/WeightedSummation.d.ts +3 -1
- package/dist/runtime/computations/WeightedSummation.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/transaction.d.ts +15 -0
- package/dist/runtime/transaction.d.ts.map +1 -0
- package/dist/storage/erstorage/EntityQueryHandle.d.ts +1 -0
- package/dist/storage/erstorage/EntityQueryHandle.d.ts.map +1 -1
- package/dist/storage/erstorage/QueryExecutor.d.ts +1 -1
- package/dist/storage/erstorage/QueryExecutor.d.ts.map +1 -1
- package/dist/storage/erstorage/RecordQueryAgent.d.ts +1 -0
- package/dist/storage/erstorage/RecordQueryAgent.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -553,7 +553,7 @@ EventSource.create<TArgs, TResult>(
|
|
|
553
553
|
```typescript
|
|
554
554
|
async function(this: Controller, args: TArgs): Promise<TResult>
|
|
555
555
|
```
|
|
556
|
-
- `config.afterDispatch` (function, optional): Hook called
|
|
556
|
+
- `config.afterDispatch` (function, optional): Hook called inside the retryable transaction attempt. Can return additional context, but must be retry-safe and must not perform irreversible external IO.
|
|
557
557
|
```typescript
|
|
558
558
|
async function(this: Controller, args: TArgs, result: { data?: TResult }): Promise<Record<string, unknown> | void>
|
|
559
559
|
```
|
|
@@ -664,7 +664,7 @@ const result = await controller.dispatch(webhookSource, {
|
|
|
664
664
|
2. `guard` runs before event processing; throw to reject the event
|
|
665
665
|
3. `mapEventData` converts dispatch args into the format stored in the entity
|
|
666
666
|
4. `resolve` returns data to the caller (useful for query-type events)
|
|
667
|
-
5. `afterDispatch` runs
|
|
667
|
+
5. `afterDispatch` runs inside the retryable transaction attempt and can return additional context
|
|
668
668
|
6. The Controller automatically registers the event source's entity if not already in the entities list
|
|
669
669
|
7. Interaction is a built-in EventSource type that provides pre-built `guard`, `mapEventData`, and `resolve` implementations
|
|
670
670
|
|
|
@@ -1631,6 +1631,13 @@ Custom.create(config: CustomConfig): CustomInstance
|
|
|
1631
1631
|
- For accessing dictionaries: use `type: 'global'` with `source: DictionaryInstance`
|
|
1632
1632
|
- `config.useLastValue` (boolean, optional): Whether to use last computed value in incremental computation
|
|
1633
1633
|
- `config.attributeQuery` (AttributeQueryData, optional): Attribute query configuration
|
|
1634
|
+
- `config.concurrency` (`'serializable' | 'atomic-safe'`, optional): Defaults to `'serializable'`. Serializable custom computations are retried in PostgreSQL `SERIALIZABLE` transactions. Use `'atomic-safe'` only when the callback is explicitly written with atomic state, idempotent patches, or other safe primitives.
|
|
1635
|
+
|
|
1636
|
+
**Retry safety**
|
|
1637
|
+
|
|
1638
|
+
Custom `compute`, `incrementalCompute`, `incrementalPatchCompute`, and `asyncReturn` callbacks may be replayed after transaction retry. Keep them deterministic and avoid irreversible external IO. Put post-commit external work in `recordMutationSideEffects`.
|
|
1639
|
+
|
|
1640
|
+
For async custom computations, `ComputationResult.async({ freshnessKey })` can override the default freshness stream. Property async freshness is scoped to the host record, global async freshness is scoped to the global result, and entity/relation async freshness defaults to the result target.
|
|
1634
1641
|
|
|
1635
1642
|
**Examples**
|
|
1636
1643
|
|
|
@@ -3376,7 +3383,7 @@ type DispatchResponse = {
|
|
|
3376
3383
|
2. Execute `guard` (if provided and `ignoreGuard` is false)
|
|
3377
3384
|
3. Map event data via `mapEventData` and create event record
|
|
3378
3385
|
4. Execute `resolve` (if provided) - returns data
|
|
3379
|
-
5. Execute `afterDispatch` (if provided) - returns context
|
|
3386
|
+
5. Execute `afterDispatch` (if provided) inside the retryable transaction attempt - returns context
|
|
3380
3387
|
6. Commit transaction
|
|
3381
3388
|
7. Run RecordMutationSideEffects
|
|
3382
3389
|
|
|
@@ -3465,9 +3472,10 @@ interface Storage {
|
|
|
3465
3472
|
map: any
|
|
3466
3473
|
|
|
3467
3474
|
// Transaction operations
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3475
|
+
runInTransaction: <T>(
|
|
3476
|
+
options: { name?: string; isolation?: 'READ COMMITTED' | 'SERIALIZABLE' },
|
|
3477
|
+
fn: () => Promise<T>
|
|
3478
|
+
) => Promise<T>
|
|
3471
3479
|
|
|
3472
3480
|
// Dictionary-specific API
|
|
3473
3481
|
dict: {
|
|
@@ -3506,22 +3514,12 @@ interface Storage {
|
|
|
3506
3514
|
|
|
3507
3515
|
#### Transaction Operations
|
|
3508
3516
|
|
|
3509
|
-
**
|
|
3510
|
-
|
|
3511
|
-
```typescript
|
|
3512
|
-
await storage.beginTransaction('updateOrder')
|
|
3513
|
-
```
|
|
3514
|
-
|
|
3515
|
-
**commitTransaction(transactionName?: string)**
|
|
3516
|
-
Commit a database transaction.
|
|
3517
|
+
**runInTransaction(options, fn)**
|
|
3518
|
+
Run a callback inside a database transaction. The callback form is the only supported transaction boundary because it keeps the transaction connection bound to the full async chain.
|
|
3517
3519
|
```typescript
|
|
3518
|
-
await storage.
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
**rollbackTransaction(transactionName?: string)**
|
|
3522
|
-
Rollback a database transaction.
|
|
3523
|
-
```typescript
|
|
3524
|
-
await storage.rollbackTransaction('updateOrder')
|
|
3520
|
+
await storage.runInTransaction({ name: 'updateOrder' }, async () => {
|
|
3521
|
+
await storage.update('Order', match, data)
|
|
3522
|
+
})
|
|
3525
3523
|
```
|
|
3526
3524
|
|
|
3527
3525
|
#### Entity/Relation Operations
|
|
@@ -5,6 +5,12 @@ Computations are the reactive core of interaqt, connecting interactions to entit
|
|
|
5
5
|
|
|
6
6
|
## Types of Computations
|
|
7
7
|
|
|
8
|
+
## Retry Safety
|
|
9
|
+
|
|
10
|
+
Computation callbacks may be replayed under PostgreSQL transaction retry. Keep callbacks deterministic and database-focused. Do not perform irreversible external IO in `compute`, `incrementalCompute`, `incrementalPatchCompute`, Transform callbacks, StateMachine compute functions, or `asyncReturn`.
|
|
11
|
+
|
|
12
|
+
For custom computations, the default concurrency mode is `serializable`; use `concurrency: 'atomic-safe'` only when the callback is explicitly safe under concurrent `READ COMMITTED` execution.
|
|
13
|
+
|
|
8
14
|
### 1. Transform - Creates Entities/Relations
|
|
9
15
|
|
|
10
16
|
**ONLY use in Entity/Relation computation, NEVER in Property!**
|
|
@@ -206,6 +206,8 @@ async setup(controller: Controller) {
|
|
|
206
206
|
|
|
207
207
|
**Purpose**: Define side effects that synchronize reactive data changes to external systems.
|
|
208
208
|
|
|
209
|
+
`RecordMutationSideEffect` is the recommended place for irreversible external IO. Interaction callbacks, custom computation callbacks, `afterDispatch`, and `asyncReturn` may be replayed by PostgreSQL transaction retry; side effects run after the final successful commit.
|
|
210
|
+
|
|
209
211
|
**Use Cases**:
|
|
210
212
|
- Push data mutations to external APIs
|
|
211
213
|
- Publish messages to message queues
|
|
@@ -81,6 +81,14 @@ Reactive computation is a **declarative way of defining data**:
|
|
|
81
81
|
- **Incremental computation**: Framework uses efficient incremental algorithms to avoid unnecessary recomputation
|
|
82
82
|
- **Persistent**: Computation results are stored in the database for fast queries
|
|
83
83
|
|
|
84
|
+
### PostgreSQL Concurrency Guarantees
|
|
85
|
+
|
|
86
|
+
Built-in computations such as Count, Summation, Average, Every, Any, WeightedSummation, StateMachine, and data-based Transform use atomic state updates, row locks, or unique indexes on PostgreSQL. They are safe when multiple Node.js processes share one PostgreSQL database.
|
|
87
|
+
|
|
88
|
+
Custom computations are different because interaqt cannot inspect user callback logic. `Custom.create()` defaults to `concurrency: 'serializable'`, so the framework promotes the transaction to PostgreSQL `SERIALIZABLE` and retries on `40001` / `40P01`. Use `concurrency: 'atomic-safe'` only when the custom computation is explicitly written with atomic state, idempotent patches, or other safe primitives.
|
|
89
|
+
|
|
90
|
+
Because retry replays the transaction attempt, `guard`, `mapEventData`, `resolve`, computation callbacks, `afterDispatch`, and `asyncReturn` must be deterministic and retry-safe. Put irreversible external IO in `recordMutationSideEffects`, which runs after the final commit.
|
|
91
|
+
|
|
84
92
|
### Core Principle: Data Existence
|
|
85
93
|
|
|
86
94
|
In interaqt, all data has its "reason for existence":
|
|
@@ -21,6 +21,19 @@ const result = await controller.callInteraction('CreatePost', {
|
|
|
21
21
|
});
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
## Retry-Safe Interaction Callbacks
|
|
25
|
+
|
|
26
|
+
`Controller.dispatch()` runs interaction processing inside a retryable transaction. PostgreSQL SERIALIZABLE promotion or retryable SQLSTATE errors (`40001`, `40P01`) may replay the transaction attempt.
|
|
27
|
+
|
|
28
|
+
These interaction callbacks must be deterministic and retry-safe:
|
|
29
|
+
|
|
30
|
+
- `guard`
|
|
31
|
+
- `mapEventData`
|
|
32
|
+
- `resolve`
|
|
33
|
+
- `afterDispatch`
|
|
34
|
+
|
|
35
|
+
`afterDispatch` runs before commit inside the retryable transaction attempt. It can return response context or perform retry-safe database work, but it must not perform irreversible external IO. Put emails, webhooks, message publishing, payment calls, and other post-commit external effects in `recordMutationSideEffects`.
|
|
36
|
+
|
|
24
37
|
## Basic Concepts of Interactions
|
|
25
38
|
|
|
26
39
|
### What is an Interaction
|
|
@@ -205,6 +205,19 @@ const currentWeather = await system.storage.get('state', 'currentWeather');
|
|
|
205
205
|
console.log('Current weather:', currentWeather);
|
|
206
206
|
```
|
|
207
207
|
|
|
208
|
+
### Retry and Freshness Semantics
|
|
209
|
+
|
|
210
|
+
`handleAsyncReturn()` runs inside the same retryable transaction model as `Controller.dispatch()`. If PostgreSQL reports a retryable transaction error, or if the async result applies a custom/full-replace path that requires `SERIALIZABLE`, interaqt may replay the async return attempt.
|
|
211
|
+
|
|
212
|
+
Keep `asyncReturn` deterministic and database-focused. Do not send emails, call payment APIs, publish messages, or perform other irreversible external IO from `asyncReturn`; those effects can be duplicated by a retry. Put irreversible post-commit work in `recordMutationSideEffects`.
|
|
213
|
+
|
|
214
|
+
Async tasks also use a freshness key so stale results do not overwrite newer work:
|
|
215
|
+
|
|
216
|
+
- Property async computations default to a key scoped by computation and host record.
|
|
217
|
+
- Global async computations default to a key scoped by computation and global result.
|
|
218
|
+
- Entity and relation async computations default to the result target, which means each target has one global freshness stream.
|
|
219
|
+
- Pass an explicit `freshnessKey` to `ComputationResult.async({ freshnessKey })` when multiple independent async streams should be allowed for the same entity or relation target.
|
|
220
|
+
|
|
208
221
|
## Implementing Entity Async Computations
|
|
209
222
|
|
|
210
223
|
### Use Cases
|
|
@@ -13,10 +13,10 @@ Many LLMs generate incorrect API usage. Here's the correct way to use interaqt t
|
|
|
13
13
|
controller.run() // ❌ No such method
|
|
14
14
|
storage.findByProperty('Entity', 'prop') // ❌ No such method
|
|
15
15
|
controller.execute() // ❌ No such method
|
|
16
|
-
controller.dispatch() // ❌ No such method
|
|
17
16
|
|
|
18
17
|
// ✅ CORRECT: Use these APIs instead
|
|
19
|
-
controller.callInteraction('InteractionName', args) // ✅ Call
|
|
18
|
+
controller.callInteraction('InteractionName', args) // ✅ Call interaction by name
|
|
19
|
+
controller.dispatch(InteractionObject, args) // ✅ Dispatch an event source object
|
|
20
20
|
storage.findOne('Entity', MatchExp) // ✅ Find single record
|
|
21
21
|
storage.find('Entity', MatchExp) // ✅ Find multiple records
|
|
22
22
|
storage.create('Entity', data) // ✅ Create record
|
|
@@ -139,6 +139,16 @@ describe('Feature Tests', () => {
|
|
|
139
139
|
})
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
+
### PostgreSQL Concurrency Tests
|
|
143
|
+
|
|
144
|
+
For changes that affect runtime transactions, custom computations, async computations, PostgreSQL id generation, or reactive computation state, run the real PostgreSQL suite:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
INTERAQT_POSTGRES_DATABASE=interaqt_test npm run test:postgres-concurrency
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This script fails when the database environment variable is missing. Plain `npm test` may skip PostgreSQL-specific tests in local lightweight environments.
|
|
151
|
+
|
|
142
152
|
### Key API Methods
|
|
143
153
|
|
|
144
154
|
#### 1. Controller APIs
|
|
@@ -514,6 +514,16 @@ Transform.create(config: TransformConfig): KlassInstance<typeof Transform>
|
|
|
514
514
|
- `config.callback` (function, required): Transformation function that converts source data to target data
|
|
515
515
|
- `config.attributeQuery` (AttributeQueryData, required): Attribute query configuration
|
|
516
516
|
|
|
517
|
+
### Custom.create()
|
|
518
|
+
|
|
519
|
+
Create a custom computation when built-in computations are not expressive enough.
|
|
520
|
+
|
|
521
|
+
**Concurrency parameter**
|
|
522
|
+
- `config.concurrency` (optional): `'serializable' | 'atomic-safe'`, defaults to `'serializable'`.
|
|
523
|
+
- `'serializable'`: interaqt runs the custom computation in a retryable PostgreSQL `SERIALIZABLE` transaction.
|
|
524
|
+
- `'atomic-safe'`: you explicitly promise the custom computation only uses atomic state, idempotent patches, or other concurrency-safe primitives. Full recompute and entity/relation full replace paths still require SERIALIZABLE even for `atomic-safe` custom computations.
|
|
525
|
+
|
|
526
|
+
Custom callbacks may be replayed after retryable transaction failures. Do not perform irreversible external IO inside custom `compute`, `incrementalCompute`, `incrementalPatchCompute`, or `asyncReturn`; use `recordMutationSideEffects` for post-commit external work.
|
|
517
527
|
|
|
518
528
|
### StateMachine.create()
|
|
519
529
|
|
|
@@ -53,6 +53,9 @@ import {
|
|
|
53
53
|
// Storage and Query
|
|
54
54
|
Controller,
|
|
55
55
|
MonoSystem,
|
|
56
|
+
runWithTransactionRetry,
|
|
57
|
+
isRetryableTransactionError,
|
|
58
|
+
isRequireSerializableRetry,
|
|
56
59
|
|
|
57
60
|
// Dictionary (Global State)
|
|
58
61
|
Dictionary,
|
|
@@ -173,4 +176,6 @@ const controller = new Controller({
|
|
|
173
176
|
|
|
174
177
|
4. **Filtered Entities**: Created using `Entity.create()` with `baseEntity` and `filterCondition`, not a separate import.
|
|
175
178
|
|
|
176
|
-
5. **Database Drivers**: Choose one based on your needs - PGLiteDB for in-memory testing, PostgreSQLDB for production, etc.
|
|
179
|
+
5. **Database Drivers**: Choose one based on your needs - PGLiteDB for in-memory testing, PostgreSQLDB for production, etc.
|
|
180
|
+
|
|
181
|
+
6. **Transaction helpers**: `runWithTransactionRetry`, `isRetryableTransactionError`, and `isRequireSerializableRetry` are exported for advanced runtime integrations and tests. Most application code should use `Controller.dispatch()` or `system.storage.runInTransaction()` instead of calling retry helpers directly.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# PostgreSQL Concurrency Migration
|
|
2
|
+
|
|
3
|
+
This note summarizes user-visible changes from the PostgreSQL reactive computation concurrency fix.
|
|
4
|
+
|
|
5
|
+
## What Changed
|
|
6
|
+
|
|
7
|
+
interaqt now uses PostgreSQL as the concurrency coordinator for multi-process deployments:
|
|
8
|
+
|
|
9
|
+
- Built-in computations use atomic state updates, row locks, unique indexes, or SERIALIZABLE retry where needed.
|
|
10
|
+
- PostgreSQL id generation uses native sequences instead of writing `_IDS_`.
|
|
11
|
+
- Custom computations default to retryable `SERIALIZABLE` execution.
|
|
12
|
+
- Async return handling runs in a retryable transaction and applies freshness checks.
|
|
13
|
+
|
|
14
|
+
## Callback Replay Rules
|
|
15
|
+
|
|
16
|
+
The following callbacks may be replayed after SERIALIZABLE promotion, `40001`, or `40P01`:
|
|
17
|
+
|
|
18
|
+
- `guard`
|
|
19
|
+
- `mapEventData`
|
|
20
|
+
- `resolve`
|
|
21
|
+
- computation callbacks
|
|
22
|
+
- `afterDispatch`
|
|
23
|
+
- `asyncReturn`
|
|
24
|
+
|
|
25
|
+
Keep these callbacks deterministic. Do not send emails, charge payments, call irreversible external APIs, publish messages, or write non-transactional resources from these callbacks.
|
|
26
|
+
|
|
27
|
+
Use `recordMutationSideEffects` for irreversible external IO. Side effects run after the final successful commit and are not replayed for failed attempts.
|
|
28
|
+
|
|
29
|
+
## Custom Computation Concurrency
|
|
30
|
+
|
|
31
|
+
`Custom.create()` now defaults to:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
Custom.create({
|
|
35
|
+
name: 'MyComputation',
|
|
36
|
+
concurrency: 'serializable',
|
|
37
|
+
// ...
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Use `concurrency: 'atomic-safe'` only when the custom computation is explicitly safe under concurrent PostgreSQL `READ COMMITTED` execution, for example because it only uses atomic state or idempotent patches.
|
|
42
|
+
|
|
43
|
+
Even with `atomic-safe`, full recompute and entity/relation full replace paths still require SERIALIZABLE.
|
|
44
|
+
|
|
45
|
+
## Async Return Freshness
|
|
46
|
+
|
|
47
|
+
`handleAsyncReturn()` locks the task row and checks whether the task is still current.
|
|
48
|
+
|
|
49
|
+
Default freshness streams:
|
|
50
|
+
|
|
51
|
+
- Property async computation: scoped to the host record.
|
|
52
|
+
- Global async computation: scoped to the global result.
|
|
53
|
+
- Entity/relation async computation: scoped to the result target.
|
|
54
|
+
|
|
55
|
+
Pass an explicit `freshnessKey` when one entity or relation target needs multiple independent async streams:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
return ComputationResult.async({
|
|
59
|
+
freshnessKey: `tenant:${tenantId}:job:${jobId}`,
|
|
60
|
+
// task args...
|
|
61
|
+
})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Stale tasks are marked `skipped` and do not call `asyncReturn`.
|
|
65
|
+
|
|
66
|
+
## PostgreSQL ID Sequences
|
|
67
|
+
|
|
68
|
+
PostgreSQL ids are allocated with native sequences.
|
|
69
|
+
|
|
70
|
+
Migration behavior:
|
|
71
|
+
|
|
72
|
+
- New databases start at id `1`.
|
|
73
|
+
- Existing table max id is used to initialize the sequence.
|
|
74
|
+
- Existing `_IDS_` rows are read as legacy migration input when the table exists.
|
|
75
|
+
- Databases without `_IDS_` are supported.
|
|
76
|
+
- Shared physical tables use one sequence per physical table/id field.
|
|
77
|
+
|
|
78
|
+
Do not write `_IDS_` to control ids. `_IDS_` is legacy input only.
|
|
79
|
+
|
|
80
|
+
PostgreSQL sequence gaps are normal after rollback or failed transactions. Do not depend on contiguous ids.
|
|
81
|
+
|
|
82
|
+
## Transaction API
|
|
83
|
+
|
|
84
|
+
Use callback transactions:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
await system.storage.runInTransaction(
|
|
88
|
+
{ name: 'my-operation', isolation: 'SERIALIZABLE' },
|
|
89
|
+
async () => {
|
|
90
|
+
// transactional work
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Do not use old manual transaction APIs such as `beginTransaction`, `commitTransaction`, or `rollbackTransaction`.
|
|
96
|
+
|
|
97
|
+
## Testing PostgreSQL Concurrency
|
|
98
|
+
|
|
99
|
+
Run the real PostgreSQL concurrency suite with:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
INTERAQT_POSTGRES_DATABASE=interaqt_test npm run test:postgres-concurrency
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This script intentionally fails when `INTERAQT_POSTGRES_DATABASE` is missing, so PostgreSQL concurrency coverage cannot silently skip in CI.
|
|
@@ -142,6 +142,7 @@ Remember: **Stop thinking "how to do", start thinking "what is"**!
|
|
|
142
142
|
18. [Performance Optimization](./17-performance-optimization.md) - Performance tips
|
|
143
143
|
19. [API Exports Reference](./18-api-exports-reference.md) - Complete list of available imports
|
|
144
144
|
20. [Common Anti-Patterns](./19-common-anti-patterns.md) - Mistakes to avoid
|
|
145
|
+
21. [PostgreSQL Concurrency Migration](./20-postgresql-concurrency-migration.md) - Retry, async, and sequence migration notes
|
|
145
146
|
|
|
146
147
|
## 📞 Need Help?
|
|
147
148
|
|
package/dist/core/Custom.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IInstance } from './interfaces.js';
|
|
2
2
|
import { DataDep } from './Computation.js';
|
|
3
|
+
export type CustomConcurrency = 'serializable' | 'atomic-safe';
|
|
3
4
|
export interface CustomInstance extends IInstance {
|
|
4
5
|
name: string;
|
|
5
6
|
dataDeps?: {
|
|
@@ -10,8 +11,18 @@ export interface CustomInstance extends IInstance {
|
|
|
10
11
|
incrementalPatchCompute?: Function;
|
|
11
12
|
createState?: Function;
|
|
12
13
|
getInitialValue?: Function;
|
|
14
|
+
/**
|
|
15
|
+
* Runs inside the retryable transaction attempt when async task results are
|
|
16
|
+
* applied. Keep it deterministic and free of irreversible external IO.
|
|
17
|
+
*/
|
|
13
18
|
asyncReturn?: Function;
|
|
14
19
|
useLastValue?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Defaults to 'serializable'. Use 'atomic-safe' only when the custom
|
|
22
|
+
* computation's incremental path is built from framework atomic primitives or
|
|
23
|
+
* otherwise remains correct under READ COMMITTED retry boundaries.
|
|
24
|
+
*/
|
|
25
|
+
concurrency?: CustomConcurrency;
|
|
15
26
|
}
|
|
16
27
|
export interface CustomCreateArgs {
|
|
17
28
|
name: string;
|
|
@@ -25,6 +36,7 @@ export interface CustomCreateArgs {
|
|
|
25
36
|
getInitialValue?: Function;
|
|
26
37
|
asyncReturn?: Function;
|
|
27
38
|
useLastValue?: boolean;
|
|
39
|
+
concurrency?: CustomConcurrency;
|
|
28
40
|
}
|
|
29
41
|
export declare class Custom implements CustomInstance {
|
|
30
42
|
uuid: string;
|
|
@@ -43,6 +55,7 @@ export declare class Custom implements CustomInstance {
|
|
|
43
55
|
getInitialValue?: Function;
|
|
44
56
|
asyncReturn?: Function;
|
|
45
57
|
useLastValue?: boolean;
|
|
58
|
+
concurrency?: CustomConcurrency;
|
|
46
59
|
constructor(args: CustomCreateArgs, options?: {
|
|
47
60
|
uuid?: string;
|
|
48
61
|
});
|
|
@@ -95,6 +108,11 @@ export declare class Custom implements CustomInstance {
|
|
|
95
108
|
collection: false;
|
|
96
109
|
required: false;
|
|
97
110
|
};
|
|
111
|
+
concurrency: {
|
|
112
|
+
type: "string";
|
|
113
|
+
collection: false;
|
|
114
|
+
required: false;
|
|
115
|
+
};
|
|
98
116
|
};
|
|
99
117
|
static create(args: CustomCreateArgs, options?: {
|
|
100
118
|
uuid?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Custom.d.ts","sourceRoot":"","sources":["../../src/core/Custom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgC,MAAM,iBAAiB,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACtC,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,kBAAkB,CAAC,EAAE,QAAQ,CAAC;IAC9B,uBAAuB,CAAC,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Custom.d.ts","sourceRoot":"","sources":["../../src/core/Custom.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,9 +4,26 @@ type CallbackThis = any;
|
|
|
4
4
|
export interface EventSourceInstance<TArgs = unknown, TResult = void> extends IInstance {
|
|
5
5
|
name: string;
|
|
6
6
|
entity: EntityInstance;
|
|
7
|
+
/**
|
|
8
|
+
* Runs inside the dispatch transaction attempt. It may be replayed when the
|
|
9
|
+
* transaction is promoted or retried, so it must be deterministic and must
|
|
10
|
+
* not perform irreversible external IO.
|
|
11
|
+
*/
|
|
7
12
|
guard?: (this: CallbackThis, args: TArgs) => Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Runs inside the dispatch transaction attempt and may be replayed on retry.
|
|
15
|
+
*/
|
|
8
16
|
mapEventData?: (args: TArgs) => Record<string, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Runs inside the dispatch transaction attempt and may be replayed on retry.
|
|
19
|
+
* External side effects should be modeled with record mutation side effects,
|
|
20
|
+
* which run after the final successful commit.
|
|
21
|
+
*/
|
|
9
22
|
resolve?: (this: CallbackThis, args: TArgs) => Promise<TResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Runs before commit inside the retryable transaction attempt. It may produce
|
|
25
|
+
* response context, but it must not perform irreversible external IO.
|
|
26
|
+
*/
|
|
10
27
|
afterDispatch?: (this: CallbackThis, args: TArgs, result: {
|
|
11
28
|
data?: TResult;
|
|
12
29
|
}) => Promise<Record<string, unknown> | void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventSource.d.ts","sourceRoot":"","sources":["../../src/core/EventSource.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EventSource.d.ts","sourceRoot":"","sources":["../../src/core/EventSource.ts"],"names":[],"mappings":"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"}
|
package/dist/drivers/PGLite.d.ts
CHANGED
|
@@ -15,8 +15,10 @@ export declare class PGLiteDB implements Database {
|
|
|
15
15
|
idSystem: IDSystem;
|
|
16
16
|
logger: DatabaseLogger;
|
|
17
17
|
db: InstanceType<typeof PGlite>;
|
|
18
|
+
supportsSelectForUpdate: boolean;
|
|
18
19
|
constructor(database?: string | undefined, options?: PGLiteDBConfig);
|
|
19
20
|
open(forceDrop?: boolean): Promise<void>;
|
|
21
|
+
setupInternalComputationState(): Promise<void>;
|
|
20
22
|
query<T>(sql: string, params?: unknown[], name?: string): Promise<T[]>;
|
|
21
23
|
update<T>(sql: string, values: unknown[], idField?: string, name?: string): Promise<T[]>;
|
|
22
24
|
insert(sql: string, values: unknown[], name?: string): Promise<EntityIdRef>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PGLite.d.ts","sourceRoot":"","sources":["../../src/drivers/PGLite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,EAA4E,MAAM,UAAU,CAAC;AAC1I,OAAO,EAAE,MAAM,EAAC,MAAM,sBAAsB,CAAA;AAG5C,cAAM,QAAQ;IACS,EAAE,EAAE,QAAQ;gBAAZ,EAAE,EAAE,QAAQ;IAC/B,KAAK;IAGC,SAAS,CAAC,UAAU,EAAE,MAAM;CAGrC;AAED,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,CAAC,EAAE,cAAc,CAAA;CAAE,CAAA;AAExD,qBAAa,QAAS,YAAW,QAAQ;
|
|
1
|
+
{"version":3,"file":"PGLite.d.ts","sourceRoot":"","sources":["../../src/drivers/PGLite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,EAA4E,MAAM,UAAU,CAAC;AAC1I,OAAO,EAAE,MAAM,EAAC,MAAM,sBAAsB,CAAA;AAG5C,cAAM,QAAQ;IACS,EAAE,EAAE,QAAQ;gBAAZ,EAAE,EAAE,QAAQ;IAC/B,KAAK;IAGC,SAAS,CAAC,UAAU,EAAE,MAAM;CAGrC;AAED,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,CAAC,EAAE,cAAc,CAAA;CAAE,CAAA;AAExD,qBAAa,QAAS,YAAW,QAAQ;IAKlB,QAAQ,CAAC,EAAC,MAAM;IAAS,OAAO,EAAE,cAAc;IAJnE,QAAQ,EAAG,QAAQ,CAAA;IACnB,MAAM,EAAE,cAAc,CAAA;IACtB,EAAE,EAAE,YAAY,CAAC,OAAO,MAAM,CAAC,CAAA;IAC/B,uBAAuB,UAAO;gBACX,QAAQ,CAAC,EAAC,MAAM,YAAA,EAAS,OAAO,GAAE,cAAmB;IAKlE,IAAI,CAAC,SAAS,UAAQ;IAqBtB,6BAA6B;IAU7B,KAAK,CAAC,CAAC,EAAE,GAAG,EAAC,MAAM,EAAE,MAAM,GAAE,OAAO,EAAM,EAAE,IAAI,SAAI;IAuBpD,MAAM,CAAC,CAAC,EAAE,GAAG,EAAC,MAAM,EAAC,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAC,MAAM,EAAE,IAAI,SAAG;IAgBhE,MAAM,CAAC,GAAG,EAAC,MAAM,EAAE,MAAM,EAAC,OAAO,EAAE,EAAE,IAAI,SAAG;IA2B5C,MAAM,CAAC,CAAC,EAAG,GAAG,EAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,SAAG;IAYjD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAG;IAoBjC,KAAK;IAGC,SAAS,CAAC,UAAU,EAAE,MAAM;IAGlC,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC,EAAE,MAAM,MAAM;;;;IAYzL,cAAc;IAOd,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO;CAmBtD"}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
import { Database, DatabaseLogger, EntityIdRef } from '..';
|
|
1
|
+
import { Database, DatabaseLogger, EntityIdRef, TransactionOptions } from '..';
|
|
2
2
|
import { default as pg, ClientConfig } from 'pg';
|
|
3
|
-
declare const Client: typeof pg.Client;
|
|
3
|
+
declare const Client: typeof pg.Client, Pool: typeof pg.Pool;
|
|
4
4
|
declare class IDSystem {
|
|
5
|
-
db:
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
db: PostgreSQLDB;
|
|
6
|
+
private initialized;
|
|
7
|
+
private recordToSequenceName;
|
|
8
|
+
constructor(db: PostgreSQLDB);
|
|
9
|
+
setup(): Promise<pg.QueryResult<any>>;
|
|
10
|
+
private sanitizeIdentifierPart;
|
|
11
|
+
sequenceName(recordName: string): string;
|
|
12
|
+
private sequenceNameForKey;
|
|
13
|
+
private quoteIdentifier;
|
|
14
|
+
setupSequences(records: Array<{
|
|
15
|
+
recordName: string;
|
|
16
|
+
tableName: string;
|
|
17
|
+
idField: string;
|
|
18
|
+
}>): Promise<void>;
|
|
8
19
|
getAutoId(recordName: string): Promise<string>;
|
|
9
20
|
}
|
|
10
21
|
export type PostgreSQLDBConfig = Omit<ClientConfig, 'database'> & {
|
|
@@ -16,8 +27,14 @@ export declare class PostgreSQLDB implements Database {
|
|
|
16
27
|
idSystem: IDSystem;
|
|
17
28
|
logger: DatabaseLogger;
|
|
18
29
|
db: InstanceType<typeof Client>;
|
|
30
|
+
pool?: InstanceType<typeof Pool>;
|
|
31
|
+
private transactionContext;
|
|
32
|
+
supportsSelectForUpdate: boolean;
|
|
19
33
|
constructor(database: string, options?: PostgreSQLDBConfig);
|
|
20
34
|
open(forceDrop?: boolean): Promise<void>;
|
|
35
|
+
private getQueryable;
|
|
36
|
+
runInTransaction<T>(options: TransactionOptions, fn: () => Promise<T>): Promise<T>;
|
|
37
|
+
setupInternalComputationState(): Promise<void>;
|
|
21
38
|
query<T>(sql: string, where?: unknown[], name?: string): Promise<T[]>;
|
|
22
39
|
update<T>(sql: string, values: unknown[], idField?: string, name?: string): Promise<T[]>;
|
|
23
40
|
insert(sql: string, values: unknown[], name?: string): Promise<EntityIdRef>;
|
|
@@ -25,6 +42,11 @@ export declare class PostgreSQLDB implements Database {
|
|
|
25
42
|
scheme(sql: string, name?: string): Promise<pg.QueryResult<any>>;
|
|
26
43
|
close(): Promise<void>;
|
|
27
44
|
getAutoId(recordName: string): Promise<string>;
|
|
45
|
+
setupRecordSequences(records: Array<{
|
|
46
|
+
recordName: string;
|
|
47
|
+
tableName: string;
|
|
48
|
+
idField: string;
|
|
49
|
+
}>): Promise<void>;
|
|
28
50
|
parseMatchExpression(key: string, value: [string, string], fieldName: string, fieldType: string, isReferenceValue: boolean, getReferenceFieldValue: (v: string) => string, p: () => string): {
|
|
29
51
|
fieldValue: string;
|
|
30
52
|
fieldParams: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgreSQL.d.ts","sourceRoot":"","sources":["../../src/drivers/PostgreSQL.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"PostgreSQL.d.ts","sourceRoot":"","sources":["../../src/drivers/PostgreSQL.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAuG,kBAAkB,EAAC,MAAM,UAAU,CAAC;AAGxL,OAAO,EAAE,EAAE,EAAE,KAAK,YAAY,EAAkB,MAAM,IAAI,CAAA;AAE1D,QAAA,MAAQ,MAAM,oBAAE,IAAI,gBAAO,CAAA;AAQ3B,cAAM,QAAQ;IAGS,EAAE,EAAE,YAAY;IAFnC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,oBAAoB,CAA4B;gBACrC,EAAE,EAAE,YAAY;IACnC,KAAK;IAGL,OAAO,CAAC,sBAAsB;IAI9B,YAAY,CAAC,UAAU,EAAE,MAAM;IAG/B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,eAAe;IAGjB,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAsCzF,SAAS,CAAC,UAAU,EAAE,MAAM;CAYrC;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,cAAc,CAAA;CAAE,CAAA;AAE7F,qBAAa,YAAa,YAAW,QAAQ;IAOtB,QAAQ,EAAC,MAAM;IAAS,OAAO,EAAE,kBAAkB;IANtE,QAAQ,EAAG,QAAQ,CAAA;IACnB,MAAM,EAAE,cAAc,CAAA;IACtB,EAAE,EAAE,YAAY,CAAC,OAAO,MAAM,CAAC,CAAA;IAC/B,IAAI,CAAC,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,CAAA;IAChC,OAAO,CAAC,kBAAkB,CAA8C;IACxE,uBAAuB,UAAO;gBACX,QAAQ,EAAC,MAAM,EAAS,OAAO,GAAE,kBAAuB;IAKrE,IAAI,CAAC,SAAS,UAAQ;IA4B5B,OAAO,CAAC,YAAY;IAQd,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAuClF,6BAA6B;IAU7B,KAAK,CAAC,CAAC,EAAE,GAAG,EAAC,MAAM,EAAE,KAAK,GAAE,OAAO,EAAM,EAAE,IAAI,SAAI;IAanD,MAAM,CAAC,CAAC,EAAE,GAAG,EAAC,MAAM,EAAC,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAC,MAAM,EAAE,IAAI,SAAG;IAehE,MAAM,CAAC,GAAG,EAAC,MAAM,EAAE,MAAM,EAAC,OAAO,EAAE,EAAE,IAAI,SAAG;IAgB5C,MAAM,CAAC,CAAC,EAAG,GAAG,EAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,SAAG;IAYhD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAG;IAUjC,KAAK;IAGC,SAAS,CAAC,UAAU,EAAE,MAAM;IAGlC,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAG/F,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC,EAAE,MAAM,MAAM;;;;IAYzL,cAAc;IAOd,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO;CAmBtD"}
|
package/dist/drivers/SQLite.d.ts
CHANGED
|
@@ -15,8 +15,10 @@ export declare class SQLiteDB implements Database {
|
|
|
15
15
|
db: InstanceType<typeof SQLite>;
|
|
16
16
|
idSystem: IDSystem;
|
|
17
17
|
logger: DatabaseLogger;
|
|
18
|
+
supportsSelectForUpdate: boolean;
|
|
18
19
|
constructor(file?: string, options?: SQLiteDBOptions | undefined);
|
|
19
20
|
open(): Promise<void>;
|
|
21
|
+
setupInternalComputationState(): Promise<void>;
|
|
20
22
|
query<T>(sql: string, where?: unknown[], name?: string): Promise<T[]>;
|
|
21
23
|
update(sql: string, values: unknown[], idField?: string, name?: string): Promise<EntityIdRef[]>;
|
|
22
24
|
insert(sql: string, values: unknown[], name?: string): Promise<EntityIdRef>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SQLite.d.ts","sourceRoot":"","sources":["../../src/drivers/SQLite.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,EAA4E,MAAM,UAAU,CAAC;AAE1I,cAAM,QAAQ;IACS,EAAE,EAAE,QAAQ;gBAAZ,EAAE,EAAE,QAAQ;IAC/B,KAAK;IAGC,SAAS,CAAC,UAAU,EAAE,MAAM;CAWrC;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,CAAA;AAEvF,qBAAa,QAAS,YAAW,QAAQ;
|
|
1
|
+
{"version":3,"file":"SQLite.d.ts","sourceRoot":"","sources":["../../src/drivers/SQLite.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,EAA4E,MAAM,UAAU,CAAC;AAE1I,cAAM,QAAQ;IACS,EAAE,EAAE,QAAQ;gBAAZ,EAAE,EAAE,QAAQ;IAC/B,KAAK;IAGC,SAAS,CAAC,UAAU,EAAE,MAAM;CAWrC;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,CAAA;AAEvF,qBAAa,QAAS,YAAW,QAAQ;IAKlB,IAAI,EAAC,MAAM;IAAsB,OAAO,CAAC,EAAE,eAAe;IAJ7E,EAAE,EAAG,YAAY,CAAC,OAAO,MAAM,CAAC,CAAA;IAChC,QAAQ,EAAG,QAAQ,CAAA;IACnB,MAAM,EAAE,cAAc,CAAA;IACtB,uBAAuB,UAAQ;gBACZ,IAAI,GAAC,MAAmB,EAAS,OAAO,CAAC,EAAE,eAAe,YAAA;IAIvE,IAAI;IAIJ,6BAA6B;IAU7B,KAAK,CAAC,CAAC,EAAE,GAAG,EAAC,MAAM,EAAE,KAAK,GAAE,OAAO,EAAM,EAAE,IAAI,SAAI;IAanD,MAAM,CAAC,GAAG,EAAC,MAAM,EAAC,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAC,MAAM,EAAE,IAAI,SAAG;IAe7D,MAAM,CAAE,GAAG,EAAC,MAAM,EAAE,MAAM,EAAC,OAAO,EAAE,EAAE,IAAI,SAAG;IAc7C,MAAM,CAAC,CAAC,EAAG,GAAG,EAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,SAAG;IAYhD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAG;IAU3B,KAAK;IAGL,SAAS,CAAC,UAAU,EAAE,MAAM;IAGlC,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC,EAAE,MAAM,MAAM;;;;IAczL,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO;CAmBtD"}
|