@optimystic/db-core 0.1.0 → 0.4.2

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 (89) hide show
  1. package/README.md +8 -0
  2. package/dist/index.min.js +1 -1
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/blocks/block-types.d.ts +1 -1
  5. package/dist/src/blocks/block-types.d.ts.map +1 -1
  6. package/dist/src/btree/btree.d.ts.map +1 -1
  7. package/dist/src/btree/btree.js +3 -5
  8. package/dist/src/btree/btree.js.map +1 -1
  9. package/dist/src/btree/independent-trunk.d.ts +4 -4
  10. package/dist/src/btree/independent-trunk.d.ts.map +1 -1
  11. package/dist/src/btree/independent-trunk.js +2 -2
  12. package/dist/src/btree/independent-trunk.js.map +1 -1
  13. package/dist/src/btree/path.d.ts +1 -1
  14. package/dist/src/btree/path.d.ts.map +1 -1
  15. package/dist/src/btree/tree-block.d.ts +1 -1
  16. package/dist/src/btree/tree-block.d.ts.map +1 -1
  17. package/dist/src/btree/tree-block.js +2 -2
  18. package/dist/src/btree/tree-block.js.map +1 -1
  19. package/dist/src/btree/trunk.d.ts +3 -3
  20. package/dist/src/btree/trunk.d.ts.map +1 -1
  21. package/dist/src/collection/collection.d.ts +5 -1
  22. package/dist/src/collection/collection.d.ts.map +1 -1
  23. package/dist/src/collection/collection.js +77 -50
  24. package/dist/src/collection/collection.js.map +1 -1
  25. package/dist/src/collections/diary/diary.d.ts +2 -0
  26. package/dist/src/collections/diary/diary.d.ts.map +1 -1
  27. package/dist/src/collections/diary/diary.js +4 -0
  28. package/dist/src/collections/diary/diary.js.map +1 -1
  29. package/dist/src/collections/tree/struct.d.ts.map +1 -1
  30. package/dist/src/collections/tree/struct.js +2 -1
  31. package/dist/src/collections/tree/struct.js.map +1 -1
  32. package/dist/src/index.d.ts +1 -0
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +1 -0
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/transaction/coordinator.d.ts.map +1 -1
  37. package/dist/src/transaction/coordinator.js +14 -19
  38. package/dist/src/transaction/coordinator.js.map +1 -1
  39. package/dist/src/transaction/transaction.d.ts.map +1 -1
  40. package/dist/src/transaction/transaction.js +1 -13
  41. package/dist/src/transaction/transaction.js.map +1 -1
  42. package/dist/src/transaction/validator.d.ts.map +1 -1
  43. package/dist/src/transaction/validator.js +5 -9
  44. package/dist/src/transaction/validator.js.map +1 -1
  45. package/dist/src/transactor/network-transactor.d.ts.map +1 -1
  46. package/dist/src/transactor/network-transactor.js +29 -3
  47. package/dist/src/transactor/network-transactor.js.map +1 -1
  48. package/dist/src/transactor/transactor-source.js +1 -1
  49. package/dist/src/transactor/transactor-source.js.map +1 -1
  50. package/dist/src/transform/cache-source.js +3 -3
  51. package/dist/src/transform/cache-source.js.map +1 -1
  52. package/dist/src/transform/helpers.d.ts +27 -2
  53. package/dist/src/transform/helpers.d.ts.map +1 -1
  54. package/dist/src/transform/helpers.js +44 -14
  55. package/dist/src/transform/helpers.js.map +1 -1
  56. package/dist/src/transform/struct.d.ts +5 -4
  57. package/dist/src/transform/struct.d.ts.map +1 -1
  58. package/dist/src/transform/tracker.d.ts.map +1 -1
  59. package/dist/src/transform/tracker.js +18 -9
  60. package/dist/src/transform/tracker.js.map +1 -1
  61. package/dist/src/utility/batch-coordinator.js +0 -1
  62. package/dist/src/utility/batch-coordinator.js.map +1 -1
  63. package/dist/src/utility/hash-string.d.ts +11 -0
  64. package/dist/src/utility/hash-string.d.ts.map +1 -0
  65. package/dist/src/utility/hash-string.js +17 -0
  66. package/dist/src/utility/hash-string.js.map +1 -0
  67. package/package.json +14 -8
  68. package/src/blocks/block-types.ts +1 -1
  69. package/src/blocks/structs.ts +1 -1
  70. package/src/btree/btree.ts +3 -5
  71. package/src/btree/independent-trunk.ts +6 -6
  72. package/src/btree/path.ts +1 -1
  73. package/src/btree/tree-block.ts +3 -3
  74. package/src/btree/trunk.ts +3 -3
  75. package/src/collection/collection.ts +78 -51
  76. package/src/collections/diary/diary.ts +5 -0
  77. package/src/collections/tree/struct.ts +2 -1
  78. package/src/index.ts +1 -0
  79. package/src/transaction/coordinator.ts +14 -18
  80. package/src/transaction/session.ts +182 -182
  81. package/src/transaction/transaction.ts +2 -13
  82. package/src/transaction/validator.ts +147 -150
  83. package/src/transactor/network-transactor.ts +32 -2
  84. package/src/transactor/transactor-source.ts +1 -1
  85. package/src/transform/cache-source.ts +3 -3
  86. package/src/transform/helpers.ts +44 -14
  87. package/src/transform/struct.ts +5 -6
  88. package/src/transform/tracker.ts +16 -9
  89. package/src/utility/hash-string.ts +17 -0
@@ -1,182 +1,182 @@
1
- import type { TransactionCoordinator } from "./coordinator.js";
2
- import type { Transaction, ExecutionResult, ITransactionEngine, TransactionStamp, CollectionActions } from "./transaction.js";
3
- import { createTransactionStamp, createTransactionId } from "./transaction.js";
4
-
5
- /**
6
- * TransactionSession manages incremental transaction building.
7
- *
8
- * This is the high-level API for building transactions incrementally:
9
- * - Stamp is created at BEGIN (stable throughout transaction)
10
- * - Execute statements one at a time
11
- * - Engine translates statements to actions (if not already provided)
12
- * - Actions are immediately applied to collections via coordinator.applyActions()
13
- * - On commit, all statements are compiled into a complete Transaction
14
- * - The Transaction is then committed through coordinator.commit() for PEND/COMMIT orchestration
15
- *
16
- * Usage:
17
- * const session = new TransactionSession(coordinator, engine);
18
- * await session.execute('INSERT INTO users (id, name) VALUES (?, ?)', [1, 'Alice']);
19
- * await session.execute('SELECT * FROM orders WHERE user_id = ?', [1]);
20
- * const result = await session.commit();
21
- *
22
- * For validation/replay, use engine.execute() directly with a complete Transaction.
23
- */
24
- export class TransactionSession {
25
- private readonly statements: string[] = [];
26
- private readonly stamp: TransactionStamp;
27
- private committed = false;
28
- private rolledBack = false;
29
-
30
- constructor(
31
- private readonly coordinator: TransactionCoordinator,
32
- private readonly engine: ITransactionEngine,
33
- peerId: string = 'local', // TODO: Get from coordinator or config
34
- schemaHash: string = '' // TODO: Get from engine
35
- ) {
36
- // Create stamp at BEGIN (stable throughout transaction)
37
- this.stamp = createTransactionStamp(
38
- peerId,
39
- Date.now(),
40
- schemaHash,
41
- 'unknown' // TODO: Get engine ID from engine
42
- );
43
- }
44
-
45
- /**
46
- * Execute a statement.
47
- *
48
- * If actions are provided, they are applied directly.
49
- * Otherwise, the engine translates the statement to actions.
50
- *
51
- * @param statement - The statement to execute (engine-specific, e.g., SQL statement)
52
- * @param actions - Optional pre-computed actions (for Quereus module case)
53
- * @returns Execution result with any returned values
54
- */
55
- async execute(statement: string, actions?: CollectionActions[]): Promise<{ success: boolean; error?: string }> {
56
- if (this.committed) {
57
- return { success: false, error: 'Transaction already committed' };
58
- }
59
- if (this.rolledBack) {
60
- return { success: false, error: 'Transaction already rolled back' };
61
- }
62
-
63
- try {
64
- // If actions not provided, enlist engine to translate statement
65
- let actionsToApply: CollectionActions[];
66
- if (actions) {
67
- actionsToApply = actions;
68
- } else {
69
- // Create a temporary transaction with just this statement for translation
70
- const tempTransaction: Transaction = {
71
- stamp: this.stamp,
72
- statements: [statement],
73
- reads: [],
74
- id: 'temp' // Temporary ID for translation only
75
- };
76
- const result = await this.engine.execute(tempTransaction);
77
- if (!result.success || !result.actions) {
78
- return { success: false, error: result.error || 'Failed to translate statement' };
79
- }
80
- actionsToApply = result.actions;
81
- }
82
-
83
- // Apply actions through coordinator
84
- await this.coordinator.applyActions(actionsToApply, this.stamp.id);
85
-
86
- // Accumulate the statement for later compilation
87
- this.statements.push(statement);
88
-
89
- return { success: true };
90
- } catch (error) {
91
- return {
92
- success: false,
93
- error: `Failed to execute statement: ${error instanceof Error ? error.message : String(error)}`
94
- };
95
- }
96
- }
97
-
98
- /**
99
- * Commit the transaction.
100
- *
101
- * Compiles all statements into a complete Transaction and commits through coordinator.
102
- */
103
- async commit(): Promise<ExecutionResult> {
104
- if (this.committed) {
105
- return { success: false, error: 'Transaction already committed' };
106
- }
107
- if (this.rolledBack) {
108
- return { success: false, error: 'Transaction already rolled back' };
109
- }
110
-
111
- // Create the complete transaction
112
- const transaction: Transaction = {
113
- stamp: this.stamp,
114
- statements: this.statements,
115
- reads: [], // TODO: Track reads during statement execution
116
- id: createTransactionId(this.stamp.id, this.statements, [])
117
- };
118
-
119
- // Commit through coordinator (which will orchestrate PEND/COMMIT)
120
- await this.coordinator.commit(transaction);
121
-
122
- this.committed = true;
123
- return { success: true };
124
- }
125
-
126
- /**
127
- * Rollback the transaction (discard local state).
128
- *
129
- * Note: Actions have already been applied to collections' trackers.
130
- * Rollback just prevents commit and clears session state.
131
- * Collections will discard tracker state when they sync or update.
132
- */
133
- async rollback(): Promise<void> {
134
- if (this.committed) {
135
- throw new Error('Cannot rollback: transaction already committed');
136
- }
137
- if (this.rolledBack) {
138
- throw new Error('Transaction already rolled back');
139
- }
140
-
141
- // Rollback through coordinator
142
- await this.coordinator.rollback(this.stamp.id);
143
- this.rolledBack = true;
144
- this.statements.length = 0;
145
- }
146
-
147
- /**
148
- * Get the transaction stamp ID (stable throughout transaction).
149
- */
150
- getStampId(): string {
151
- return this.stamp.id;
152
- }
153
-
154
- /**
155
- * Get the transaction stamp (full metadata).
156
- */
157
- getStamp(): TransactionStamp {
158
- return this.stamp;
159
- }
160
-
161
- /**
162
- * Get the list of accumulated statements.
163
- */
164
- getStatements(): readonly string[] {
165
- return this.statements;
166
- }
167
-
168
- /**
169
- * Check if the transaction has been committed.
170
- */
171
- isCommitted(): boolean {
172
- return this.committed;
173
- }
174
-
175
- /**
176
- * Check if the transaction has been rolled back.
177
- */
178
- isRolledBack(): boolean {
179
- return this.rolledBack;
180
- }
181
- }
182
-
1
+ import type { TransactionCoordinator } from "./coordinator.js";
2
+ import type { Transaction, ExecutionResult, ITransactionEngine, TransactionStamp, CollectionActions } from "./transaction.js";
3
+ import { createTransactionStamp, createTransactionId } from "./transaction.js";
4
+
5
+ /**
6
+ * TransactionSession manages incremental transaction building.
7
+ *
8
+ * This is the high-level API for building transactions incrementally:
9
+ * - Stamp is created at BEGIN (stable throughout transaction)
10
+ * - Execute statements one at a time
11
+ * - Engine translates statements to actions (if not already provided)
12
+ * - Actions are immediately applied to collections via coordinator.applyActions()
13
+ * - On commit, all statements are compiled into a complete Transaction
14
+ * - The Transaction is then committed through coordinator.commit() for PEND/COMMIT orchestration
15
+ *
16
+ * Usage:
17
+ * const session = new TransactionSession(coordinator, engine);
18
+ * await session.execute('INSERT INTO users (id, name) VALUES (?, ?)', [1, 'Alice']);
19
+ * await session.execute('SELECT * FROM orders WHERE user_id = ?', [1]);
20
+ * const result = await session.commit();
21
+ *
22
+ * For validation/replay, use engine.execute() directly with a complete Transaction.
23
+ */
24
+ export class TransactionSession {
25
+ private readonly statements: string[] = [];
26
+ private readonly stamp: TransactionStamp;
27
+ private committed = false;
28
+ private rolledBack = false;
29
+
30
+ constructor(
31
+ private readonly coordinator: TransactionCoordinator,
32
+ private readonly engine: ITransactionEngine,
33
+ peerId: string = 'local', // TODO: Get from coordinator or config
34
+ schemaHash: string = '' // TODO: Get from engine
35
+ ) {
36
+ // Create stamp at BEGIN (stable throughout transaction)
37
+ this.stamp = createTransactionStamp(
38
+ peerId,
39
+ Date.now(),
40
+ schemaHash,
41
+ 'unknown' // TODO: Get engine ID from engine
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Execute a statement.
47
+ *
48
+ * If actions are provided, they are applied directly.
49
+ * Otherwise, the engine translates the statement to actions.
50
+ *
51
+ * @param statement - The statement to execute (engine-specific, e.g., SQL statement)
52
+ * @param actions - Optional pre-computed actions (for Quereus module case)
53
+ * @returns Execution result with any returned values
54
+ */
55
+ async execute(statement: string, actions?: CollectionActions[]): Promise<{ success: boolean; error?: string }> {
56
+ if (this.committed) {
57
+ return { success: false, error: 'Transaction already committed' };
58
+ }
59
+ if (this.rolledBack) {
60
+ return { success: false, error: 'Transaction already rolled back' };
61
+ }
62
+
63
+ try {
64
+ // If actions not provided, enlist engine to translate statement
65
+ let actionsToApply: CollectionActions[];
66
+ if (actions) {
67
+ actionsToApply = actions;
68
+ } else {
69
+ // Create a temporary transaction with just this statement for translation
70
+ const tempTransaction: Transaction = {
71
+ stamp: this.stamp,
72
+ statements: [statement],
73
+ reads: [],
74
+ id: 'temp' // Temporary ID for translation only
75
+ };
76
+ const result = await this.engine.execute(tempTransaction);
77
+ if (!result.success || !result.actions) {
78
+ return { success: false, error: result.error || 'Failed to translate statement' };
79
+ }
80
+ actionsToApply = result.actions;
81
+ }
82
+
83
+ // Apply actions through coordinator
84
+ await this.coordinator.applyActions(actionsToApply, this.stamp.id);
85
+
86
+ // Accumulate the statement for later compilation
87
+ this.statements.push(statement);
88
+
89
+ return { success: true };
90
+ } catch (error) {
91
+ return {
92
+ success: false,
93
+ error: `Failed to execute statement: ${error instanceof Error ? error.message : String(error)}`
94
+ };
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Commit the transaction.
100
+ *
101
+ * Compiles all statements into a complete Transaction and commits through coordinator.
102
+ */
103
+ async commit(): Promise<ExecutionResult> {
104
+ if (this.committed) {
105
+ return { success: false, error: 'Transaction already committed' };
106
+ }
107
+ if (this.rolledBack) {
108
+ return { success: false, error: 'Transaction already rolled back' };
109
+ }
110
+
111
+ // Create the complete transaction
112
+ const transaction: Transaction = {
113
+ stamp: this.stamp,
114
+ statements: this.statements,
115
+ reads: [], // TODO: Track reads during statement execution
116
+ id: createTransactionId(this.stamp.id, this.statements, [])
117
+ };
118
+
119
+ // Commit through coordinator (which will orchestrate PEND/COMMIT)
120
+ await this.coordinator.commit(transaction);
121
+
122
+ this.committed = true;
123
+ return { success: true };
124
+ }
125
+
126
+ /**
127
+ * Rollback the transaction (discard local state).
128
+ *
129
+ * Note: Actions have already been applied to collections' trackers.
130
+ * Rollback just prevents commit and clears session state.
131
+ * Collections will discard tracker state when they sync or update.
132
+ */
133
+ async rollback(): Promise<void> {
134
+ if (this.committed) {
135
+ throw new Error('Cannot rollback: transaction already committed');
136
+ }
137
+ if (this.rolledBack) {
138
+ throw new Error('Transaction already rolled back');
139
+ }
140
+
141
+ // Rollback through coordinator
142
+ await this.coordinator.rollback(this.stamp.id);
143
+ this.rolledBack = true;
144
+ this.statements.length = 0;
145
+ }
146
+
147
+ /**
148
+ * Get the transaction stamp ID (stable throughout transaction).
149
+ */
150
+ getStampId(): string {
151
+ return this.stamp.id;
152
+ }
153
+
154
+ /**
155
+ * Get the transaction stamp (full metadata).
156
+ */
157
+ getStamp(): TransactionStamp {
158
+ return this.stamp;
159
+ }
160
+
161
+ /**
162
+ * Get the list of accumulated statements.
163
+ */
164
+ getStatements(): readonly string[] {
165
+ return this.statements;
166
+ }
167
+
168
+ /**
169
+ * Check if the transaction has been committed.
170
+ */
171
+ isCommitted(): boolean {
172
+ return this.committed;
173
+ }
174
+
175
+ /**
176
+ * Check if the transaction has been rolled back.
177
+ */
178
+ isRolledBack(): boolean {
179
+ return this.rolledBack;
180
+ }
181
+ }
182
+
@@ -1,5 +1,6 @@
1
1
  import type { BlockId } from "../blocks/index.js";
2
2
  import type { CollectionId } from "../collection/index.js";
3
+ import { hashString } from "../utility/hash-string.js";
3
4
 
4
5
  /**
5
6
  * Transaction Stamp: Created at BEGIN, stable throughout transaction lifecycle.
@@ -94,19 +95,7 @@ export function createTransactionId(
94
95
  return `tx:${hashString(txData)}`;
95
96
  }
96
97
 
97
- /**
98
- * Simple hash function for creating IDs.
99
- * Uses a basic hash for now - can be replaced with proper cryptographic hash later.
100
- */
101
- function hashString(str: string): string {
102
- let hash = 0;
103
- for (let i = 0; i < str.length; i++) {
104
- const char = str.charCodeAt(i);
105
- hash = ((hash << 5) - hash) + char;
106
- hash = hash & hash; // Convert to 32-bit integer
107
- }
108
- return Math.abs(hash).toString(36);
109
- }
98
+
110
99
 
111
100
  /**
112
101
  * Transaction engine interface.