@livestore/livestore 0.0.0-snapshot-909cdd1ac2fd591945c2be2b0f53e14d87f3c9d4

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 (131) hide show
  1. package/README.md +1 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/QueryCache.d.ts +20 -0
  4. package/dist/QueryCache.d.ts.map +1 -0
  5. package/dist/QueryCache.js +61 -0
  6. package/dist/QueryCache.js.map +1 -0
  7. package/dist/SynchronousDatabaseWrapper.d.ts +36 -0
  8. package/dist/SynchronousDatabaseWrapper.d.ts.map +1 -0
  9. package/dist/SynchronousDatabaseWrapper.js +176 -0
  10. package/dist/SynchronousDatabaseWrapper.js.map +1 -0
  11. package/dist/effect/LiveStore.d.ts +38 -0
  12. package/dist/effect/LiveStore.d.ts.map +1 -0
  13. package/dist/effect/LiveStore.js +38 -0
  14. package/dist/effect/LiveStore.js.map +1 -0
  15. package/dist/effect/index.d.ts +2 -0
  16. package/dist/effect/index.d.ts.map +1 -0
  17. package/dist/effect/index.js +2 -0
  18. package/dist/effect/index.js.map +1 -0
  19. package/dist/global-state.d.ts +14 -0
  20. package/dist/global-state.d.ts.map +1 -0
  21. package/dist/global-state.js +16 -0
  22. package/dist/global-state.js.map +1 -0
  23. package/dist/index.d.ts +19 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +15 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/reactive.d.ts +163 -0
  28. package/dist/reactive.d.ts.map +1 -0
  29. package/dist/reactive.js +382 -0
  30. package/dist/reactive.js.map +1 -0
  31. package/dist/reactive.test.d.ts +2 -0
  32. package/dist/reactive.test.d.ts.map +1 -0
  33. package/dist/reactive.test.js +345 -0
  34. package/dist/reactive.test.js.map +1 -0
  35. package/dist/reactiveQueries/base-class.d.ts +59 -0
  36. package/dist/reactiveQueries/base-class.d.ts.map +1 -0
  37. package/dist/reactiveQueries/base-class.js +29 -0
  38. package/dist/reactiveQueries/base-class.js.map +1 -0
  39. package/dist/reactiveQueries/graphql.d.ts +52 -0
  40. package/dist/reactiveQueries/graphql.d.ts.map +1 -0
  41. package/dist/reactiveQueries/graphql.js +136 -0
  42. package/dist/reactiveQueries/graphql.js.map +1 -0
  43. package/dist/reactiveQueries/js.d.ts +35 -0
  44. package/dist/reactiveQueries/js.d.ts.map +1 -0
  45. package/dist/reactiveQueries/js.js +57 -0
  46. package/dist/reactiveQueries/js.js.map +1 -0
  47. package/dist/reactiveQueries/sql.d.ts +49 -0
  48. package/dist/reactiveQueries/sql.d.ts.map +1 -0
  49. package/dist/reactiveQueries/sql.js +130 -0
  50. package/dist/reactiveQueries/sql.js.map +1 -0
  51. package/dist/reactiveQueries/sql.test.d.ts +2 -0
  52. package/dist/reactiveQueries/sql.test.d.ts.map +1 -0
  53. package/dist/reactiveQueries/sql.test.js +284 -0
  54. package/dist/reactiveQueries/sql.test.js.map +1 -0
  55. package/dist/row-query.d.ts +33 -0
  56. package/dist/row-query.d.ts.map +1 -0
  57. package/dist/row-query.js +84 -0
  58. package/dist/row-query.js.map +1 -0
  59. package/dist/store-context.d.ts +26 -0
  60. package/dist/store-context.d.ts.map +1 -0
  61. package/dist/store-context.js +6 -0
  62. package/dist/store-context.js.map +1 -0
  63. package/dist/store-devtools.d.ts +19 -0
  64. package/dist/store-devtools.d.ts.map +1 -0
  65. package/dist/store-devtools.js +141 -0
  66. package/dist/store-devtools.js.map +1 -0
  67. package/dist/store.d.ts +175 -0
  68. package/dist/store.d.ts.map +1 -0
  69. package/dist/store.js +507 -0
  70. package/dist/store.js.map +1 -0
  71. package/dist/utils/data-structures.d.ts +10 -0
  72. package/dist/utils/data-structures.d.ts.map +1 -0
  73. package/dist/utils/data-structures.js +32 -0
  74. package/dist/utils/data-structures.js.map +1 -0
  75. package/dist/utils/dev.d.ts +3 -0
  76. package/dist/utils/dev.d.ts.map +1 -0
  77. package/dist/utils/dev.js +17 -0
  78. package/dist/utils/dev.js.map +1 -0
  79. package/dist/utils/otel.d.ts +4 -0
  80. package/dist/utils/otel.d.ts.map +1 -0
  81. package/dist/utils/otel.js +6 -0
  82. package/dist/utils/otel.js.map +1 -0
  83. package/dist/utils/stack-info.d.ts +10 -0
  84. package/dist/utils/stack-info.d.ts.map +1 -0
  85. package/dist/utils/stack-info.js +41 -0
  86. package/dist/utils/stack-info.js.map +1 -0
  87. package/dist/utils/stack-info.test.d.ts +2 -0
  88. package/dist/utils/stack-info.test.d.ts.map +1 -0
  89. package/dist/utils/stack-info.test.js +75 -0
  90. package/dist/utils/stack-info.test.js.map +1 -0
  91. package/dist/utils/tests/fixture.d.ts +259 -0
  92. package/dist/utils/tests/fixture.d.ts.map +1 -0
  93. package/dist/utils/tests/fixture.js +33 -0
  94. package/dist/utils/tests/fixture.js.map +1 -0
  95. package/dist/utils/tests/mod.d.ts +3 -0
  96. package/dist/utils/tests/mod.d.ts.map +1 -0
  97. package/dist/utils/tests/mod.js +3 -0
  98. package/dist/utils/tests/mod.js.map +1 -0
  99. package/dist/utils/tests/otel.d.ts +10 -0
  100. package/dist/utils/tests/otel.d.ts.map +1 -0
  101. package/dist/utils/tests/otel.js +42 -0
  102. package/dist/utils/tests/otel.js.map +1 -0
  103. package/package.json +60 -0
  104. package/src/QueryCache.ts +81 -0
  105. package/src/SynchronousDatabaseWrapper.ts +256 -0
  106. package/src/ambient.d.ts +10 -0
  107. package/src/effect/LiveStore.ts +112 -0
  108. package/src/effect/index.ts +8 -0
  109. package/src/global-state.ts +20 -0
  110. package/src/index.ts +64 -0
  111. package/src/reactive.test.ts +426 -0
  112. package/src/reactive.ts +661 -0
  113. package/src/reactiveQueries/base-class.ts +115 -0
  114. package/src/reactiveQueries/graphql.ts +233 -0
  115. package/src/reactiveQueries/js.ts +108 -0
  116. package/src/reactiveQueries/sql.test.ts +308 -0
  117. package/src/reactiveQueries/sql.ts +226 -0
  118. package/src/row-query.ts +200 -0
  119. package/src/store-context.ts +23 -0
  120. package/src/store-devtools.ts +217 -0
  121. package/src/store.ts +920 -0
  122. package/src/utils/data-structures.ts +36 -0
  123. package/src/utils/dev.ts +24 -0
  124. package/src/utils/otel.ts +9 -0
  125. package/src/utils/stack-info.test.ts +79 -0
  126. package/src/utils/stack-info.ts +54 -0
  127. package/src/utils/tests/fixture.ts +77 -0
  128. package/src/utils/tests/mod.ts +2 -0
  129. package/src/utils/tests/otel.ts +61 -0
  130. package/tsconfig.json +18 -0
  131. package/vitest.config.js +9 -0
@@ -0,0 +1,20 @@
1
+ import type { Bindable } from '@livestore/common';
2
+ type Opaque<BaseType, BrandType = unknown> = BaseType & {
3
+ readonly [Symbols.base]: BaseType;
4
+ readonly [Symbols.brand]: BrandType;
5
+ };
6
+ declare namespace Symbols {
7
+ const base: unique symbol;
8
+ const brand: unique symbol;
9
+ }
10
+ export type CacheKey = Opaque<string, string>;
11
+ export default class QueryCache {
12
+ #private;
13
+ getKey: (sql: string, bindValues?: Bindable) => CacheKey;
14
+ get: (key: CacheKey) => any;
15
+ set: (queriedTables: Iterable<string>, key: CacheKey, results: any) => void;
16
+ ignoreQuery: (query: string) => boolean;
17
+ invalidate: (queriedTables: Iterable<string>) => void;
18
+ }
19
+ export {};
20
+ //# sourceMappingURL=QueryCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryCache.d.ts","sourceRoot":"","sources":["../src/QueryCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAGjD,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,IAAI,QAAQ,GAAG;IACtD,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAA;IACjC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CACpC,CAAA;AAED,kBAAU,OAAO,CAAC;IACD,MAAM,IAAI,EAAE,OAAO,MAAM,CAAA;IACzB,MAAM,KAAK,EAAE,OAAO,MAAM,CAAA;CAC1C;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAO7C,MAAM,CAAC,OAAO,OAAO,UAAU;;IAI7B,MAAM,QAAS,MAAM,eAAe,QAAQ,KAAG,QAAQ,CAUtD;IAED,GAAG,QAAS,QAAQ,SAEnB;IAED,GAAG,kBAAmB,QAAQ,CAAC,MAAM,CAAC,OAAO,QAAQ,WAAW,GAAG,UAWlE;IAMD,WAAW,UAAW,MAAM,aAE3B;IAUD,UAAU,kBAAmB,QAAQ,CAAC,MAAM,CAAC,UAU5C;CACF"}
@@ -0,0 +1,61 @@
1
+ import { BoundMap, BoundSet } from '@livestore/common';
2
+ var Symbols;
3
+ (function (Symbols) {
4
+ })(Symbols || (Symbols = {}));
5
+ const ignore = ['begin', 'rollback', 'commit', 'savepoint', 'release'];
6
+ // TODO: profile to see how big we need this cache to be.
7
+ const cacheSize = 200;
8
+ export default class QueryCache {
9
+ #entries = new BoundMap(cacheSize);
10
+ #dependencies = new Map();
11
+ getKey = (sql, bindValues) => {
12
+ if (bindValues == null) {
13
+ return sql;
14
+ }
15
+ if (Array.isArray(bindValues)) {
16
+ return (sql + '\n' + bindValues.join('\n'));
17
+ }
18
+ return (sql + '\n' + Object.values(bindValues).join('\n'));
19
+ };
20
+ get = (key) => {
21
+ return this.#entries.get(key);
22
+ };
23
+ set = (queriedTables, key, results) => {
24
+ this.#entries.set(key, results);
25
+ for (const table of queriedTables) {
26
+ let keys = this.#dependencies.get(table);
27
+ if (keys == null) {
28
+ keys = new BoundSet(cacheSize);
29
+ keys.onEvict = this.#dependencyTrackerEvicted;
30
+ this.#dependencies.set(table, keys);
31
+ }
32
+ keys.add(key);
33
+ }
34
+ };
35
+ #dependencyTrackerEvicted = (key) => {
36
+ this.#entries.delete(key);
37
+ };
38
+ ignoreQuery = (query) => {
39
+ return ignore.some((prefix) => query.startsWith(prefix));
40
+ };
41
+ // The next simplest step is to create a specific implementation for invalidating
42
+ // the expensive track list queries only when constraints data in a write overlaps with read constraints.
43
+ //
44
+ // As well as either:
45
+ // a. removeing the big view (since we'll have our cache)
46
+ // b. incrementally updating the view on insert by the EventImporter
47
+ //
48
+ // We'll not try to tackle any generalized approach until we have a proof of concept working.
49
+ invalidate = (queriedTables) => {
50
+ for (const table of queriedTables) {
51
+ const keys = this.#dependencies.get(table);
52
+ if (keys == null) {
53
+ continue;
54
+ }
55
+ for (const k of keys) {
56
+ this.#entries.delete(k);
57
+ }
58
+ }
59
+ };
60
+ }
61
+ //# sourceMappingURL=QueryCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryCache.js","sourceRoot":"","sources":["../src/QueryCache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { DebugInfo, MutableDebugInfo, PreparedBindValues, SynchronousDatabase } from '@livestore/common';
2
+ import type * as otel from '@opentelemetry/api';
3
+ export declare const emptyDebugInfo: () => DebugInfo;
4
+ export declare class SynchronousDatabaseWrapper {
5
+ private cachedStmts;
6
+ private tablesUsedCache;
7
+ private resultCache;
8
+ private db;
9
+ private otelTracer;
10
+ private otelRootSpanContext;
11
+ private tablesUsedStmt;
12
+ debugInfo: MutableDebugInfo;
13
+ constructor({ db, otel, }: {
14
+ db: SynchronousDatabase;
15
+ otel: {
16
+ tracer: otel.Tracer;
17
+ rootSpanContext: otel.Context;
18
+ };
19
+ });
20
+ txn<TRes>(callback: () => TRes): TRes;
21
+ getTablesUsed(query: string): Set<string>;
22
+ execute(queryStr: string, bindValues?: PreparedBindValues, writeTables?: ReadonlySet<string>, options?: {
23
+ hasNoEffects?: boolean;
24
+ otelContext?: otel.Context;
25
+ }): {
26
+ durationMs: number;
27
+ };
28
+ select<T = any>(queryStr: string, options?: {
29
+ queriedTables?: ReadonlySet<string>;
30
+ bindValues?: PreparedBindValues;
31
+ skipCache?: boolean;
32
+ otelContext?: otel.Context;
33
+ }): ReadonlyArray<T>;
34
+ export(): Uint8Array;
35
+ }
36
+ //# sourceMappingURL=SynchronousDatabaseWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SynchronousDatabaseWrapper.d.ts","sourceRoot":"","sources":["../src/SynchronousDatabaseWrapper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAElB,mBAAmB,EACpB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,KAAK,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAK/C,eAAO,MAAM,cAAc,QAAO,SAKhC,CAAA;AAEF,qBAAa,0BAA0B;IAErC,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,eAAe,CAAyC;IAChE,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,EAAE,CAAqB;IAC/B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,mBAAmB,CAAc;IACzC,OAAO,CAAC,cAAc,CAAA;IACf,SAAS,EAAE,gBAAgB,CAAmB;gBAEzC,EACV,EAAE,EACF,IAAI,GACL,EAAE;QACD,EAAE,EAAE,mBAAmB,CAAA;QACvB,IAAI,EAAE;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;YACnB,eAAe,EAAE,IAAI,CAAC,OAAO,CAAA;SAC9B,CAAA;KACF;IAcD,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAqBrC,aAAa,CAAC,KAAK,EAAE,MAAM;IA4B3B,OAAO,CACL,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,kBAAkB,EAC/B,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,EACjC,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAA;KAAE,GAC/D;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE;IA8CzB,MAAM,CAAC,CAAC,GAAG,GAAG,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;QACR,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;QACnC,UAAU,CAAC,EAAE,kBAAkB,CAAA;QAC/B,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAA;KAC3B,GACA,aAAa,CAAC,CAAC,CAAC;IA+DnB,MAAM;CAQP"}
@@ -0,0 +1,176 @@
1
+ /* eslint-disable prefer-arrow/prefer-arrow-functions */
2
+ import { BoundArray, BoundMap, sql } from '@livestore/common';
3
+ import QueryCache from './QueryCache.js';
4
+ import { getDurationMsFromSpan, getStartTimeHighResFromSpan } from './utils/otel.js';
5
+ export const emptyDebugInfo = () => ({
6
+ slowQueries: new BoundArray(200),
7
+ queryFrameDuration: 0,
8
+ queryFrameCount: 0,
9
+ events: new BoundArray(1000),
10
+ });
11
+ export class SynchronousDatabaseWrapper {
12
+ // TODO: how many unique active statements are expected?
13
+ cachedStmts = new BoundMap(200);
14
+ tablesUsedCache = new BoundMap(200);
15
+ resultCache = new QueryCache();
16
+ db;
17
+ otelTracer;
18
+ otelRootSpanContext;
19
+ tablesUsedStmt;
20
+ debugInfo = emptyDebugInfo();
21
+ constructor({ db, otel, }) {
22
+ this.db = db;
23
+ this.otelTracer = otel.tracer;
24
+ this.otelRootSpanContext = otel.rootSpanContext;
25
+ this.tablesUsedStmt = db.prepare(`SELECT tbl_name FROM tables_used(?) AS u JOIN sqlite_master ON sqlite_master.name = u.name WHERE u.schema = 'main';`);
26
+ this.cachedStmts.onEvict = (_queryStr, stmt) => stmt.finalize();
27
+ configureSQLite(this);
28
+ }
29
+ txn(callback) {
30
+ this.execute(sql `begin transaction;`);
31
+ let errored = false;
32
+ let result;
33
+ try {
34
+ result = callback();
35
+ }
36
+ catch (e) {
37
+ errored = true;
38
+ this.execute(sql `rollback;`);
39
+ throw e;
40
+ }
41
+ if (!errored) {
42
+ this.execute(sql `commit;`);
43
+ }
44
+ return result;
45
+ }
46
+ getTablesUsed(query) {
47
+ // It seems that SQLite doesn't properly handle `DELETE FROM SOME_TABLE` queries without a WHERE clause
48
+ // So we need to handle these queries separately
49
+ const tableNameFromPlainDeleteQuery = tryGetTableNameFromPlainDeleteQuery(query);
50
+ if (tableNameFromPlainDeleteQuery !== undefined) {
51
+ return new Set([tableNameFromPlainDeleteQuery]);
52
+ }
53
+ const cached = this.tablesUsedCache.get(query);
54
+ if (cached) {
55
+ return cached;
56
+ }
57
+ const stmt = this.tablesUsedStmt;
58
+ const tablesUsed = new Set();
59
+ try {
60
+ const results = stmt.select([query]);
61
+ for (const row of results) {
62
+ tablesUsed.add(row.tbl_name);
63
+ }
64
+ }
65
+ catch (e) {
66
+ console.error('Error getting tables used', e, 'for query', query);
67
+ return new Set();
68
+ }
69
+ this.tablesUsedCache.set(query, tablesUsed);
70
+ return tablesUsed;
71
+ }
72
+ execute(queryStr, bindValues, writeTables, options) {
73
+ // console.debug('in-memory-db:execute', query, bindValues)
74
+ return this.otelTracer.startActiveSpan('livestore.in-memory-db:execute',
75
+ // TODO truncate query string
76
+ { attributes: { 'sql.query': queryStr } }, options?.otelContext ?? this.otelRootSpanContext, (span) => {
77
+ let stmt = this.cachedStmts.get(queryStr);
78
+ if (stmt === undefined) {
79
+ stmt = this.db.prepare(queryStr);
80
+ this.cachedStmts.set(queryStr, stmt);
81
+ }
82
+ stmt.execute(bindValues);
83
+ if (options?.hasNoEffects !== true && !this.resultCache.ignoreQuery(queryStr)) {
84
+ // TODO use write tables instead
85
+ // check what queries actually end up here.
86
+ this.resultCache.invalidate(writeTables ?? this.getTablesUsed(queryStr));
87
+ }
88
+ span.end();
89
+ const durationMs = getDurationMsFromSpan(span);
90
+ this.debugInfo.queryFrameDuration += durationMs;
91
+ this.debugInfo.queryFrameCount++;
92
+ if (durationMs > 5 && import.meta.env.DEV) {
93
+ this.debugInfo.slowQueries.push({
94
+ queryStr,
95
+ bindValues,
96
+ durationMs,
97
+ rowsCount: undefined,
98
+ queriedTables: new Set(),
99
+ startTimePerfNow: getStartTimeHighResFromSpan(span),
100
+ });
101
+ }
102
+ return { durationMs };
103
+ });
104
+ }
105
+ select(queryStr, options) {
106
+ const { queriedTables, bindValues, skipCache = false, otelContext } = options ?? {};
107
+ // console.debug('in-memory-db:select', query, bindValues)
108
+ return this.otelTracer.startActiveSpan('sql-in-memory-select', {}, otelContext ?? this.otelRootSpanContext, (span) => {
109
+ try {
110
+ span.setAttribute('sql.query', queryStr);
111
+ const key = this.resultCache.getKey(queryStr, bindValues);
112
+ const cachedResult = this.resultCache.get(key);
113
+ if (skipCache === false && cachedResult !== undefined) {
114
+ span.setAttribute('sql.rowsCount', cachedResult.length);
115
+ span.setAttribute('sql.cached', true);
116
+ span.end();
117
+ return cachedResult;
118
+ }
119
+ let stmt = this.cachedStmts.get(queryStr);
120
+ if (stmt === undefined) {
121
+ stmt = this.db.prepare(queryStr);
122
+ this.cachedStmts.set(queryStr, stmt);
123
+ }
124
+ const result = stmt.select(bindValues);
125
+ span.setAttribute('sql.rowsCount', result.length);
126
+ span.setAttribute('sql.cached', false);
127
+ const queriedTables_ = queriedTables ?? this.getTablesUsed(queryStr);
128
+ this.resultCache.set(queriedTables_, key, result);
129
+ span.end();
130
+ const durationMs = getDurationMsFromSpan(span);
131
+ this.debugInfo.queryFrameDuration += durationMs;
132
+ this.debugInfo.queryFrameCount++;
133
+ // TODO also enable in non-dev mode
134
+ if (durationMs > 5 && import.meta.env.DEV) {
135
+ this.debugInfo.slowQueries.push({
136
+ queryStr,
137
+ bindValues,
138
+ durationMs,
139
+ rowsCount: result.length,
140
+ queriedTables: queriedTables_,
141
+ startTimePerfNow: getStartTimeHighResFromSpan(span),
142
+ });
143
+ }
144
+ return result;
145
+ }
146
+ finally {
147
+ span.end();
148
+ }
149
+ });
150
+ }
151
+ export() {
152
+ // Clear statement cache because exporting frees statements
153
+ for (const key of this.cachedStmts.keys()) {
154
+ this.cachedStmts.delete(key);
155
+ }
156
+ return this.db.export();
157
+ }
158
+ }
159
+ /** Set up SQLite performance; hasn't been super carefully optimized yet. */
160
+ const configureSQLite = (db) => {
161
+ db.execute(
162
+ // TODO: revisit these tuning parameters for max performance
163
+ sql `
164
+ PRAGMA page_size=32768;
165
+ PRAGMA cache_size=10000;
166
+ PRAGMA journal_mode='MEMORY'; -- we don't flush to disk before committing a write
167
+ PRAGMA synchronous='OFF';
168
+ PRAGMA temp_store='MEMORY';
169
+ PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
170
+ `);
171
+ };
172
+ const tryGetTableNameFromPlainDeleteQuery = (query) => {
173
+ const [_, tableName] = query.trim().match(/^delete\s+from\s+(\w+)$/i) ?? [];
174
+ return tableName;
175
+ };
176
+ //# sourceMappingURL=SynchronousDatabaseWrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SynchronousDatabaseWrapper.js","sourceRoot":"","sources":["../src/SynchronousDatabaseWrapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { Adapter, BootDb, BootStatus, UnexpectedError } from '@livestore/common';
2
+ import type { LiveStoreSchema } from '@livestore/common/schema';
3
+ import type { Cause, Scope } from '@livestore/utils/effect';
4
+ import { Context, Deferred, Effect, Layer } from '@livestore/utils/effect';
5
+ import * as otel from '@opentelemetry/api';
6
+ import type { GraphQLSchema } from 'graphql';
7
+ import type { BaseGraphQLContext } from '../store.js';
8
+ import type { LiveStoreContextRunning as LiveStoreContextRunning_ } from '../store-context.js';
9
+ import type { SynchronousDatabaseWrapper } from '../SynchronousDatabaseWrapper.js';
10
+ export type LiveStoreContextRunning = LiveStoreContextRunning_;
11
+ export declare const LiveStoreContextRunning: Context.Tag<LiveStoreContextRunning_, LiveStoreContextRunning_>;
12
+ export type DeferredStoreContext = Deferred.Deferred<LiveStoreContextRunning, UnexpectedError>;
13
+ export declare const DeferredStoreContext: Context.Tag<DeferredStoreContext, DeferredStoreContext>;
14
+ export type LiveStoreContextProps<GraphQLContext extends BaseGraphQLContext> = {
15
+ schema: LiveStoreSchema;
16
+ /**
17
+ * The `storeId` can be used to isolate multiple stores from each other.
18
+ * So it can be useful for multi-tenancy scenarios.
19
+ *
20
+ * The `storeId` is also used for persistence.
21
+ *
22
+ * @default 'default'
23
+ */
24
+ storeId?: string;
25
+ graphQLOptions?: {
26
+ schema: Effect.Effect<GraphQLSchema, never, otel.Tracer>;
27
+ makeContext: (db: SynchronousDatabaseWrapper, tracer: otel.Tracer, sessionId: string) => GraphQLContext;
28
+ };
29
+ boot?: (db: BootDb) => Effect.Effect<void, unknown, otel.Tracer>;
30
+ adapter: Adapter;
31
+ disableDevtools?: boolean;
32
+ onBootStatus?: (status: BootStatus) => void;
33
+ batchUpdates: (run: () => void) => void;
34
+ };
35
+ export declare const LiveStoreContextLayer: <GraphQLContext extends BaseGraphQLContext>(props: LiveStoreContextProps<GraphQLContext>) => Layer.Layer<LiveStoreContextRunning, UnexpectedError | Cause.TimeoutException, otel.Tracer>;
36
+ export declare const LiveStoreContextDeferred: Layer.Layer<DeferredStoreContext, never, never>;
37
+ export declare const makeLiveStoreContext: <GraphQLContext extends BaseGraphQLContext>({ schema, storeId, graphQLOptions: graphQLOptions_, boot, adapter, disableDevtools, onBootStatus, batchUpdates, }: LiveStoreContextProps<GraphQLContext>) => Effect.Effect<LiveStoreContextRunning, UnexpectedError | Cause.TimeoutException, DeferredStoreContext | Scope.Scope | otel.Tracer>;
38
+ //# sourceMappingURL=LiveStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveStore.d.ts","sourceRoot":"","sources":["../../src/effect/LiveStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACrF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAY,MAAM,EAAY,KAAK,EAAoB,MAAM,yBAAyB,CAAA;AAChH,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAErD,OAAO,KAAK,EAAE,uBAAuB,IAAI,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAC9F,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAA;AAElF,MAAM,MAAM,uBAAuB,GAAG,wBAAwB,CAAA;AAC9D,eAAO,MAAM,uBAAuB,iEAEnC,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC,QAAQ,CAAC,uBAAuB,EAAE,eAAe,CAAC,CAAA;AAC9F,eAAO,MAAM,oBAAoB,yDAEhC,CAAA;AAED,MAAM,MAAM,qBAAqB,CAAC,cAAc,SAAS,kBAAkB,IAAI;IAC7E,MAAM,EAAE,eAAe,CAAA;IACvB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE;QACf,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QACxD,WAAW,EAAE,CAAC,EAAE,EAAE,0BAA0B,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,cAAc,CAAA;KACxG,CAAA;IACD,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAChE,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAA;IAC3C,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,IAAI,KAAK,IAAI,CAAA;CACxC,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,cAAc,SAAS,kBAAkB,SACtE,qBAAqB,CAAC,cAAc,CAAC,KAC3C,KAAK,CAAC,KAAK,CAAC,uBAAuB,EAAE,eAAe,GAAG,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAI1F,CAAA;AAEH,eAAO,MAAM,wBAAwB,iDAGpC,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,cAAc,SAAS,kBAAkB,qHAS3E,qBAAqB,CAAC,cAAc,CAAC,KAAG,MAAM,CAAC,MAAM,CACtD,uBAAuB,EACvB,eAAe,GAAG,KAAK,CAAC,gBAAgB,EACxC,oBAAoB,GAAG,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CA0C/C,CAAA"}
@@ -0,0 +1,38 @@
1
+ import { Context, Deferred, Duration, Effect, FiberSet, Layer, OtelTracer, pipe } from '@livestore/utils/effect';
2
+ import * as otel from '@opentelemetry/api';
3
+ import { createStore } from '../store.js';
4
+ export const LiveStoreContextRunning = Context.GenericTag('@livestore/livestore/effect/LiveStoreContextRunning');
5
+ export const DeferredStoreContext = Context.GenericTag('@livestore/livestore/effect/DeferredStoreContext');
6
+ export const LiveStoreContextLayer = (props) => Layer.scoped(LiveStoreContextRunning, makeLiveStoreContext(props)).pipe(Layer.withSpan('LiveStore'), Layer.provide(LiveStoreContextDeferred));
7
+ export const LiveStoreContextDeferred = Layer.effect(DeferredStoreContext, Deferred.make());
8
+ export const makeLiveStoreContext = ({ schema, storeId = 'default', graphQLOptions: graphQLOptions_, boot, adapter, disableDevtools, onBootStatus, batchUpdates, }) => pipe(Effect.gen(function* () {
9
+ const otelRootSpanContext = otel.context.active();
10
+ const otelTracer = yield* OtelTracer.Tracer;
11
+ const graphQLOptions = yield* graphQLOptions_
12
+ ? Effect.all({ schema: graphQLOptions_.schema, makeContext: Effect.succeed(graphQLOptions_.makeContext) })
13
+ : Effect.succeed(undefined);
14
+ // TODO join fiber set and close tear down parent scope in case of error (Needs refactor with Mike A)
15
+ const fiberSet = yield* FiberSet.make();
16
+ const store = yield* createStore({
17
+ schema,
18
+ storeId,
19
+ graphQLOptions,
20
+ otelOptions: {
21
+ tracer: otelTracer,
22
+ rootSpanContext: otelRootSpanContext,
23
+ },
24
+ boot,
25
+ adapter,
26
+ disableDevtools,
27
+ fiberSet,
28
+ onBootStatus,
29
+ batchUpdates,
30
+ });
31
+ globalThis.__debugLiveStore ??= {};
32
+ // window.__debugLiveStore[schema.key] = store
33
+ return { stage: 'running', store };
34
+ }), Effect.tapErrorCause((cause) => Effect.flatMap(DeferredStoreContext, (def) => Deferred.failCause(def, cause))), Effect.tap((storeCtx) => Effect.flatMap(DeferredStoreContext, (def) => Deferred.succeed(def, storeCtx))),
35
+ // This can take quite a while.
36
+ // TODO make this configurable
37
+ Effect.timeout(Duration.minutes(5)), Effect.withSpan('@livestore/livestore/effect:makeLiveStoreContext'));
38
+ //# sourceMappingURL=LiveStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveStore.js","sourceRoot":"","sources":["../../src/effect/LiveStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { LiveStoreContextLayer, LiveStoreContextRunning as LiveStoreContext, LiveStoreContextRunning, LiveStoreContextDeferred, DeferredStoreContext, type LiveStoreContextProps, } from './LiveStore.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/effect/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,IAAI,gBAAgB,EAC3C,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,qBAAqB,GAC3B,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { LiveStoreContextLayer, LiveStoreContextRunning as LiveStoreContext, LiveStoreContextRunning, LiveStoreContextDeferred, DeferredStoreContext, } from './LiveStore.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/effect/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,IAAI,gBAAgB,EAC3C,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,GAErB,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ *
3
+ * LiveStore currently relies on some global state in order to simplify the end-user API.
4
+ * This however also has the downside that LiveStore can't be used in multiple instances in the same app.
5
+ * It could possibly also lead to some other problems.
6
+ *
7
+ * We should find some better way to do this and ideally remove this global state.
8
+ *
9
+ * Another approach could be to use the global state by default but provide an additional way to let the user
10
+ * explicitly pass instances of state below into the LiveStore constructors.
11
+ *
12
+ */
13
+ export declare const globalReactivityGraph: import("./reactiveQueries/base-class.js").ReactivityGraph;
14
+ //# sourceMappingURL=global-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-state.d.ts","sourceRoot":"","sources":["../src/global-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,eAAO,MAAM,qBAAqB,2DAEjC,CAAA"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ *
3
+ * LiveStore currently relies on some global state in order to simplify the end-user API.
4
+ * This however also has the downside that LiveStore can't be used in multiple instances in the same app.
5
+ * It could possibly also lead to some other problems.
6
+ *
7
+ * We should find some better way to do this and ideally remove this global state.
8
+ *
9
+ * Another approach could be to use the global state by default but provide an additional way to let the user
10
+ * explicitly pass instances of state below into the LiveStore constructors.
11
+ *
12
+ */
13
+ import { GlobalValue } from '@livestore/utils/effect';
14
+ import { makeReactivityGraph } from './reactiveQueries/base-class.js';
15
+ export const globalReactivityGraph = GlobalValue.globalValue('livestore-global-reactivityGraph', () => makeReactivityGraph());
16
+ //# sourceMappingURL=global-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-state.js","sourceRoot":"","sources":["../src/global-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AAErE,MAAM,CAAC,MAAM,qBAAqB,GAAG,WAAW,CAAC,WAAW,CAAC,kCAAkC,EAAE,GAAG,EAAE,CACpG,mBAAmB,EAAE,CACtB,CAAA"}
@@ -0,0 +1,19 @@
1
+ export { Store, createStorePromise, createStore } from './store.js';
2
+ export type { BaseGraphQLContext, QueryDebugInfo, RefreshReason, CreateStoreOptions, GraphQLOptions, OtelOptions, } from './store.js';
3
+ export type { LiveStoreContextRunning } from './effect/LiveStore.js';
4
+ export { StoreAbort, StoreInterrupted, type LiveStoreContext } from './store-context.js';
5
+ export { SynchronousDatabaseWrapper, emptyDebugInfo } from './SynchronousDatabaseWrapper.js';
6
+ export type { GetAtom, AtomDebugInfo, RefreshDebugInfo, ReactiveGraphSnapshot, SerializedAtom, SerializedEffect, Atom, Node, Ref, Effect, } from './reactive.js';
7
+ export { LiveStoreJSQuery, computed } from './reactiveQueries/js.js';
8
+ export { LiveStoreSQLQuery, querySQL } from './reactiveQueries/sql.js';
9
+ export { LiveStoreGraphQLQuery, queryGraphQL } from './reactiveQueries/graphql.js';
10
+ export { type GetAtomResult, type ReactivityGraph, makeReactivityGraph, type LiveQuery, type GetResult, type LiveQueryAny, } from './reactiveQueries/base-class.js';
11
+ export { globalReactivityGraph } from './global-state.js';
12
+ export { type RowResult, type RowResultEncoded, rowQuery, deriveColQuery } from './row-query.js';
13
+ export * from '@livestore/common/schema';
14
+ export { sql, SessionIdSymbol, type BootDb, type BootStatus, type SynchronousDatabase, type DebugInfo, type MutableDebugInfo, prepareBindValues, type Bindable, type PreparedBindValues, } from '@livestore/common';
15
+ export { SqliteAst, SqliteDsl } from '@livestore/db-schema';
16
+ export { deepEqual } from '@livestore/utils';
17
+ export * from './utils/stack-info.js';
18
+ export type { ClientSession, Adapter, PreparedStatement } from '@livestore/common';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACnE,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAA;AAEnB,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAExF,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAE5F,YAAY,EACV,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,IAAI,EACJ,IAAI,EACJ,GAAG,EACH,MAAM,GACP,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAClF,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,YAAY,GAClB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEhG,cAAc,0BAA0B,CAAA;AACxC,OAAO,EACL,GAAG,EACH,eAAe,EACf,KAAK,MAAM,EACX,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,iBAAiB,EACjB,KAAK,QAAQ,EACb,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,cAAc,uBAAuB,CAAA;AAErC,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ export { Store, createStorePromise, createStore } from './store.js';
2
+ export { StoreAbort, StoreInterrupted } from './store-context.js';
3
+ export { SynchronousDatabaseWrapper, emptyDebugInfo } from './SynchronousDatabaseWrapper.js';
4
+ export { LiveStoreJSQuery, computed } from './reactiveQueries/js.js';
5
+ export { LiveStoreSQLQuery, querySQL } from './reactiveQueries/sql.js';
6
+ export { LiveStoreGraphQLQuery, queryGraphQL } from './reactiveQueries/graphql.js';
7
+ export { makeReactivityGraph, } from './reactiveQueries/base-class.js';
8
+ export { globalReactivityGraph } from './global-state.js';
9
+ export { rowQuery, deriveColQuery } from './row-query.js';
10
+ export * from '@livestore/common/schema';
11
+ export { sql, SessionIdSymbol, prepareBindValues, } from '@livestore/common';
12
+ export { SqliteAst, SqliteDsl } from '@livestore/db-schema';
13
+ export { deepEqual } from '@livestore/utils';
14
+ export * from './utils/stack-info.js';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAWnE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAyB,MAAM,oBAAoB,CAAA;AAExF,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAc5F,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAClF,OAAO,EAGL,mBAAmB,GAIpB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,EAAyC,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEhG,cAAc,0BAA0B,CAAA;AACxC,OAAO,EACL,GAAG,EACH,eAAe,EAMf,iBAAiB,GAGlB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,cAAc,uBAAuB,CAAA"}