@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,136 @@
1
+ import { shouldNeverHappen } from '@livestore/utils';
2
+ import { Schema, TreeFormatter } from '@livestore/utils/effect';
3
+ import * as otel from '@opentelemetry/api';
4
+ import * as graphql from 'graphql';
5
+ import { globalReactivityGraph } from '../global-state.js';
6
+ import { isThunk } from '../reactive.js';
7
+ import { getDurationMsFromSpan } from '../utils/otel.js';
8
+ import { LiveStoreQueryBase, makeGetAtomResult } from './base-class.js';
9
+ export const queryGraphQL = (document, genVariableValues, { label, reactivityGraph, map, } = {}) => new LiveStoreGraphQLQuery({ document, genVariableValues, label, reactivityGraph, map });
10
+ export class LiveStoreGraphQLQuery extends LiveStoreQueryBase {
11
+ _tag = 'graphql';
12
+ /** The abstract GraphQL query */
13
+ document;
14
+ /** A reactive thunk representing the query results */
15
+ results$;
16
+ variableValues$;
17
+ label;
18
+ reactivityGraph;
19
+ queryInfo = { _tag: 'None' };
20
+ mapResult;
21
+ constructor({ document, label, genVariableValues, reactivityGraph, map, }) {
22
+ super();
23
+ const labelWithDefault = label ?? graphql.getOperationAST(document)?.name?.value ?? 'graphql';
24
+ this.label = labelWithDefault;
25
+ this.document = document;
26
+ this.reactivityGraph = reactivityGraph ?? globalReactivityGraph;
27
+ this.mapResult =
28
+ map === undefined
29
+ ? (res) => res
30
+ : Schema.isSchema(map)
31
+ ? (res) => {
32
+ const parseResult = Schema.decodeEither(map)(res);
33
+ if (parseResult._tag === 'Left') {
34
+ console.error(`Error parsing GraphQL query result: ${TreeFormatter.formatErrorSync(parseResult.left)}`);
35
+ return shouldNeverHappen(`Error parsing SQL query result: ${parseResult.left}`);
36
+ }
37
+ else {
38
+ return parseResult.right;
39
+ }
40
+ }
41
+ : typeof map === 'function'
42
+ ? map
43
+ : shouldNeverHappen(`Invalid map function ${map}`);
44
+ // TODO don't even create a thunk if variables are static
45
+ let variableValues$OrvariableValues;
46
+ if (typeof genVariableValues === 'function') {
47
+ variableValues$OrvariableValues = this.reactivityGraph.makeThunk((get, _setDebugInfo, { rootOtelContext }, otelContext) => {
48
+ return genVariableValues(makeGetAtomResult(get, otelContext ?? rootOtelContext));
49
+ }, { label: `${labelWithDefault}:variableValues`, meta: { liveStoreThunkType: 'graphqlVariableValues' } });
50
+ this.variableValues$ = variableValues$OrvariableValues;
51
+ }
52
+ else {
53
+ variableValues$OrvariableValues = genVariableValues;
54
+ }
55
+ const resultsLabel = `${labelWithDefault}:results`;
56
+ this.results$ = this.reactivityGraph.makeThunk((get, setDebugInfo, { store, otelTracer, rootOtelContext }, otelContext) => {
57
+ const variableValues = isThunk(variableValues$OrvariableValues)
58
+ ? get(variableValues$OrvariableValues)
59
+ : variableValues$OrvariableValues;
60
+ const { result, queriedTables, durationMs } = this.queryOnce({
61
+ document,
62
+ variableValues,
63
+ otelContext: otelContext ?? rootOtelContext,
64
+ otelTracer,
65
+ store: store,
66
+ get: makeGetAtomResult(get, otelContext ?? rootOtelContext),
67
+ });
68
+ // Add dependencies on any tables that were used
69
+ for (const tableName of queriedTables) {
70
+ const tableRef = store.tableRefs[tableName] ?? shouldNeverHappen(`No table ref found for ${tableName}`);
71
+ get(tableRef);
72
+ }
73
+ setDebugInfo({ _tag: 'graphql', label: resultsLabel, query: graphql.print(document), durationMs });
74
+ return result;
75
+ }, { label: resultsLabel, meta: { liveStoreThunkType: 'graphqlResults' } });
76
+ }
77
+ /**
78
+ * Returns a new reactive query that contains the result of
79
+ * running an arbitrary JS computation on the results of this SQL query.
80
+ */
81
+ // pipe = <U>(fn: (result: TResult, get: GetAtomResult) => U): LiveStoreJSQuery<U> =>
82
+ // new LiveStoreJSQuery({
83
+ // fn: (get) => {
84
+ // const results = get(this.results$)
85
+ // return fn(results, get)
86
+ // },
87
+ // label: `${this.label}:js`,
88
+ // onDestroy: () => this.destroy(),
89
+ // reactivityGraph: this.reactivityGraph,
90
+ // })
91
+ queryOnce = ({ document, otelContext, otelTracer, variableValues, store, get, }) => {
92
+ const schema = store.graphQLSchema ?? shouldNeverHappen("Can't run a GraphQL query on a store without GraphQL schema");
93
+ const context = store.graphQLContext ?? shouldNeverHappen("Can't run a GraphQL query on a store without GraphQL context");
94
+ const operationName = graphql.getOperationAST(document)?.name?.value;
95
+ return otelTracer.startActiveSpan(`executeGraphQLQuery: ${operationName}`, {}, otelContext, (span) => {
96
+ span.setAttribute('graphql.variables', JSON.stringify(variableValues));
97
+ span.setAttribute('graphql.query', graphql.print(document));
98
+ context.queriedTables.clear();
99
+ context.otelContext = otel.trace.setSpan(otel.context.active(), span);
100
+ const res = graphql.executeSync({
101
+ document,
102
+ contextValue: context,
103
+ schema: schema,
104
+ variableValues,
105
+ });
106
+ // TODO track number of nested SQL queries via Otel + debug info
107
+ if (res.errors) {
108
+ span.setStatus({ code: otel.SpanStatusCode.ERROR, message: 'GraphQL error' });
109
+ span.setAttribute('graphql.error', res.errors.join('\n'));
110
+ span.setAttribute('graphql.error-detail', JSON.stringify(res.errors));
111
+ console.error(`graphql error (${operationName}) - ${res.errors.length} errors`);
112
+ for (const error of res.errors) {
113
+ console.error(error);
114
+ }
115
+ debugger;
116
+ shouldNeverHappen(`GraphQL error: ${res.errors.join('\n')}`);
117
+ }
118
+ span.end();
119
+ const result = this.mapResult(res.data, get);
120
+ const durationMs = getDurationMsFromSpan(span);
121
+ this.executionTimes.push(durationMs);
122
+ return {
123
+ result,
124
+ queriedTables: Array.from(context.queriedTables.values()),
125
+ durationMs,
126
+ };
127
+ });
128
+ };
129
+ destroy = () => {
130
+ if (this.variableValues$ !== undefined) {
131
+ this.reactivityGraph.destroyNode(this.variableValues$);
132
+ }
133
+ this.reactivityGraph.destroyNode(this.results$);
134
+ };
135
+ }
136
+ //# sourceMappingURL=graphql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../src/reactiveQueries/graphql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { QueryInfo, QueryInfoNone } from '@livestore/common';
2
+ import type { Thunk } from '../reactive.js';
3
+ import type { RefreshReason } from '../store.js';
4
+ import type { GetAtomResult, LiveQuery, QueryContext, ReactivityGraph } from './base-class.js';
5
+ import { LiveStoreQueryBase } from './base-class.js';
6
+ export declare const computed: <TResult, TQueryInfo extends QueryInfo = QueryInfoNone>(fn: (get: GetAtomResult) => TResult, options?: {
7
+ label: string;
8
+ reactivityGraph?: ReactivityGraph;
9
+ queryInfo?: TQueryInfo;
10
+ }) => LiveQuery<TResult, TQueryInfo>;
11
+ export declare class LiveStoreJSQuery<TResult, TQueryInfo extends QueryInfo = QueryInfoNone> extends LiveStoreQueryBase<TResult, TQueryInfo> {
12
+ _tag: 'js';
13
+ /** A reactive thunk representing the query results */
14
+ results$: Thunk<TResult, QueryContext, RefreshReason>;
15
+ label: string;
16
+ protected reactivityGraph: ReactivityGraph;
17
+ queryInfo: TQueryInfo;
18
+ /**
19
+ * Currently only used for "nested destruction" of piped queries
20
+ *
21
+ * i.e. when doing something like `const q = querySQL(...).pipe(...)`
22
+ * we need to also destory the SQL query when the JS query `q` is destroyed
23
+ */
24
+ private onDestroy;
25
+ constructor({ fn, label, onDestroy, reactivityGraph, queryInfo, }: {
26
+ label: string;
27
+ fn: (get: GetAtomResult) => TResult;
28
+ /** Currently only used for "nested destruction" of piped queries */
29
+ onDestroy?: () => void;
30
+ reactivityGraph?: ReactivityGraph;
31
+ queryInfo?: TQueryInfo;
32
+ });
33
+ destroy: () => void;
34
+ }
35
+ //# sourceMappingURL=js.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"js.d.ts","sourceRoot":"","sources":["../../src/reactiveQueries/js.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAIjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC9F,OAAO,EAAE,kBAAkB,EAAqB,MAAM,iBAAiB,CAAA;AAEvE,eAAO,MAAM,QAAQ,GAAI,OAAO,EAAE,UAAU,SAAS,SAAS,sBACxD,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,YACzB;IACR,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,SAAS,CAAC,EAAE,UAAU,CAAA;CACvB,KACA,SAAS,CAAC,OAAO,EAAE,UAAU,CAM5B,CAAA;AAEJ,qBAAa,gBAAgB,CAAC,OAAO,EAAE,UAAU,SAAS,SAAS,GAAG,aAAa,CAAE,SAAQ,kBAAkB,CAC7G,OAAO,EACP,UAAU,CACX;IACC,IAAI,EAAE,IAAI,CAAO;IAEjB,sDAAsD;IACtD,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,CAAC,CAAA;IAErD,KAAK,EAAE,MAAM,CAAA;IAEb,SAAS,CAAC,eAAe,EAAE,eAAe,CAAA;IAE1C,SAAS,EAAE,UAAU,CAAA;IAErB;;;;;OAKG;IACH,OAAO,CAAC,SAAS,CAA0B;gBAE/B,EACV,EAAE,EACF,KAAK,EACL,SAAS,EACT,eAAe,EACf,SAAS,GACV,EAAE;QACD,KAAK,EAAE,MAAM,CAAA;QACb,EAAE,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAA;QACnC,oEAAoE;QACpE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;QACtB,eAAe,CAAC,EAAE,eAAe,CAAA;QACjC,SAAS,CAAC,EAAE,UAAU,CAAA;KACvB;IA0CD,OAAO,aAGN;CACF"}
@@ -0,0 +1,57 @@
1
+ import * as otel from '@opentelemetry/api';
2
+ import { globalReactivityGraph } from '../global-state.js';
3
+ import { getDurationMsFromSpan } from '../utils/otel.js';
4
+ import { LiveStoreQueryBase, makeGetAtomResult } from './base-class.js';
5
+ export const computed = (fn, options) => new LiveStoreJSQuery({
6
+ fn,
7
+ label: options?.label ?? fn.toString(),
8
+ reactivityGraph: options?.reactivityGraph,
9
+ queryInfo: options?.queryInfo,
10
+ });
11
+ export class LiveStoreJSQuery extends LiveStoreQueryBase {
12
+ _tag = 'js';
13
+ /** A reactive thunk representing the query results */
14
+ results$;
15
+ label;
16
+ reactivityGraph;
17
+ queryInfo;
18
+ /**
19
+ * Currently only used for "nested destruction" of piped queries
20
+ *
21
+ * i.e. when doing something like `const q = querySQL(...).pipe(...)`
22
+ * we need to also destory the SQL query when the JS query `q` is destroyed
23
+ */
24
+ onDestroy;
25
+ constructor({ fn, label, onDestroy, reactivityGraph, queryInfo, }) {
26
+ super();
27
+ this.onDestroy = onDestroy;
28
+ this.label = label;
29
+ this.reactivityGraph = reactivityGraph ?? globalReactivityGraph;
30
+ this.queryInfo = queryInfo ?? { _tag: 'None' };
31
+ const queryLabel = `${label}:results`;
32
+ this.results$ = this.reactivityGraph.makeThunk((get, setDebugInfo, { otelTracer, rootOtelContext }, otelContext) => otelTracer.startActiveSpan(`js:${label}`, {}, otelContext ?? rootOtelContext, (span) => {
33
+ const otelContext = otel.trace.setSpan(otel.context.active(), span);
34
+ const res = fn(makeGetAtomResult(get, otelContext));
35
+ span.end();
36
+ const durationMs = getDurationMsFromSpan(span);
37
+ this.executionTimes.push(durationMs);
38
+ setDebugInfo({ _tag: 'js', label, query: fn.toString(), durationMs });
39
+ return res;
40
+ }), { label: queryLabel, meta: { liveStoreThunkType: 'jsResults' } });
41
+ }
42
+ // pipe = <U>(fn: (result: TResult, get: GetAtomResult) => U): LiveStoreJSQuery<U> =>
43
+ // new LiveStoreJSQuery({
44
+ // fn: (get) => {
45
+ // const results = get(this.results$)
46
+ // return fn(results, get)
47
+ // },
48
+ // label: `${this.label}:js`,
49
+ // onDestroy: () => this.destroy(),
50
+ // reactivityGraph: this.reactivityGraph,
51
+ // })
52
+ destroy = () => {
53
+ this.reactivityGraph.destroyNode(this.results$);
54
+ this.onDestroy?.();
55
+ };
56
+ }
57
+ //# sourceMappingURL=js.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"js.js","sourceRoot":"","sources":["../../src/reactiveQueries/js.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAE1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAG1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAExD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEvE,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,EAAmC,EACnC,OAIC,EAC+B,EAAE,CAClC,IAAI,gBAAgB,CAAsB;IACxC,EAAE;IACF,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,EAAE;IACtC,eAAe,EAAE,OAAO,EAAE,eAAe;IACzC,SAAS,EAAE,OAAO,EAAE,SAAS;CAC9B,CAAC,CAAA;AAEJ,MAAM,OAAO,gBAAwE,SAAQ,kBAG5F;IACC,IAAI,GAAS,IAAI,CAAA;IAEjB,sDAAsD;IACtD,QAAQ,CAA6C;IAErD,KAAK,CAAQ;IAEH,eAAe,CAAiB;IAE1C,SAAS,CAAY;IAErB;;;;;OAKG;IACK,SAAS,CAA0B;IAE3C,YAAY,EACV,EAAE,EACF,KAAK,EACL,SAAS,EACT,eAAe,EACf,SAAS,GAQV;QACC,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAElB,IAAI,CAAC,eAAe,GAAG,eAAe,IAAI,qBAAqB,CAAA;QAC/D,IAAI,CAAC,SAAS,GAAG,SAAS,IAAK,EAAE,IAAI,EAAE,MAAM,EAAiB,CAAA;QAE9D,MAAM,UAAU,GAAG,GAAG,KAAK,UAAU,CAAA;QAErC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5C,CAAC,GAAG,EAAE,YAAY,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,EAAE,WAAW,EAAE,EAAE,CAClE,UAAU,CAAC,eAAe,CAAC,MAAM,KAAK,EAAE,EAAE,EAAE,EAAE,WAAW,IAAI,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE;YACrF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;YACnE,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAA;YAEnD,IAAI,CAAC,GAAG,EAAE,CAAA;YAEV,MAAM,UAAU,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;YAE9C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAEpC,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,CAAA;YAErE,OAAO,GAAG,CAAA;QACZ,CAAC,CAAC,EACJ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,kBAAkB,EAAE,WAAW,EAAE,EAAE,CACjE,CAAA;IACH,CAAC;IAED,qFAAqF;IACrF,2BAA2B;IAC3B,qBAAqB;IACrB,2CAA2C;IAC3C,gCAAgC;IAChC,SAAS;IACT,iCAAiC;IACjC,uCAAuC;IACvC,6CAA6C;IAC7C,OAAO;IAEP,OAAO,GAAG,GAAG,EAAE;QACb,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC/C,IAAI,CAAC,SAAS,EAAE,EAAE,CAAA;IACpB,CAAC,CAAA;CACF"}
@@ -0,0 +1,49 @@
1
+ import { type Bindable, type QueryInfo, type QueryInfoNone } from '@livestore/common';
2
+ import { Schema } from '@livestore/utils/effect';
3
+ import type { Thunk } from '../reactive.js';
4
+ import type { RefreshReason } from '../store.js';
5
+ import type { GetAtomResult, LiveQuery, QueryContext, ReactivityGraph } from './base-class.js';
6
+ import { LiveStoreQueryBase } from './base-class.js';
7
+ /**
8
+ * NOTE `querySQL` is only supposed to read data. Don't use it to insert/update/delete data but use mutations instead.
9
+ */
10
+ export declare const querySQL: <TResultSchema, TResult = TResultSchema>(query: string | ((get: GetAtomResult) => string), options: {
11
+ schema: Schema.Schema<TResultSchema, ReadonlyArray<any>>;
12
+ map?: (rows: TResultSchema) => TResult;
13
+ /**
14
+ * Can be provided explicitly to slightly speed up initial query performance
15
+ *
16
+ * NOTE In the future we want to do this automatically at build time
17
+ */
18
+ queriedTables?: Set<string>;
19
+ bindValues?: Bindable;
20
+ label?: string;
21
+ reactivityGraph?: ReactivityGraph;
22
+ }) => LiveQuery<TResult, QueryInfoNone>;
23
+ export declare class LiveStoreSQLQuery<TResultSchema, TResult = TResultSchema, TQueryInfo extends QueryInfo = QueryInfoNone> extends LiveStoreQueryBase<TResult, TQueryInfo> {
24
+ _tag: 'sql';
25
+ /** A reactive thunk representing the query text */
26
+ queryString$: Thunk<string, QueryContext, RefreshReason> | undefined;
27
+ /** A reactive thunk representing the query results */
28
+ results$: Thunk<TResult, QueryContext, RefreshReason>;
29
+ label: string;
30
+ protected reactivityGraph: ReactivityGraph;
31
+ /** Currently only used by `rowQuery` for lazy table migrations and eager default row insertion */
32
+ private execBeforeFirstRun;
33
+ private mapResult;
34
+ private schema;
35
+ queryInfo: TQueryInfo;
36
+ constructor({ genQueryString, queriedTables, bindValues, label, reactivityGraph, schema, map, execBeforeFirstRun, queryInfo, }: {
37
+ label?: string;
38
+ genQueryString: string | ((get: GetAtomResult, ctx: QueryContext) => string);
39
+ queriedTables?: Set<string>;
40
+ bindValues?: Bindable;
41
+ reactivityGraph?: ReactivityGraph;
42
+ schema: Schema.Schema<TResultSchema, ReadonlyArray<any>>;
43
+ map?: (rows: TResultSchema) => TResult;
44
+ execBeforeFirstRun?: (ctx: QueryContext) => void;
45
+ queryInfo?: TQueryInfo;
46
+ });
47
+ destroy: () => void;
48
+ }
49
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/reactiveQueries/sql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAqB,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAExG,OAAO,EAAE,MAAM,EAAiB,MAAM,yBAAyB,CAAA;AAI/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC9F,OAAO,EAAE,kBAAkB,EAAqB,MAAM,iBAAiB,CAAA;AAEvE;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,aAAa,EAAE,OAAO,yBACtC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,aAAa,KAAK,MAAM,CAAC,WACvC;IACP,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAA;IACxD,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAA;IACtC;;;;OAIG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,UAAU,CAAC,EAAE,QAAQ,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC,KACA,SAAS,CAAC,OAAO,EAAE,aAAa,CAU/B,CAAA;AAGJ,qBAAa,iBAAiB,CAC5B,aAAa,EACb,OAAO,GAAG,aAAa,EACvB,UAAU,SAAS,SAAS,GAAG,aAAa,CAC5C,SAAQ,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC;IAC/C,IAAI,EAAE,KAAK,CAAQ;IAEnB,mDAAmD;IACnD,YAAY,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,aAAa,CAAC,GAAG,SAAS,CAAA;IAEpE,sDAAsD;IACtD,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,CAAC,CAAA;IAErD,KAAK,EAAE,MAAM,CAAA;IAEb,SAAS,CAAC,eAAe,kBAAA;IAEzB,kGAAkG;IAClG,OAAO,CAAC,kBAAkB,CAAA;IAE1B,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,MAAM,CAAkD;IAEhE,SAAS,EAAE,UAAU,CAAA;gBAET,EACV,cAAc,EACd,aAAa,EACb,UAAU,EACV,KAAiC,EACjC,eAAe,EACf,MAAM,EACN,GAAG,EACH,kBAAkB,EAClB,SAAS,GACV,EAAE;QACD,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,cAAc,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,KAAK,MAAM,CAAC,CAAA;QAC5E,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QAC3B,UAAU,CAAC,EAAE,QAAQ,CAAA;QACrB,eAAe,CAAC,EAAE,eAAe,CAAA;QACjC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAA;QACxD,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAA;QACtC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAA;QAChD,SAAS,CAAC,EAAE,UAAU,CAAA;KACvB;IAiID,OAAO,aAMN;CACF"}
@@ -0,0 +1,130 @@
1
+ import { prepareBindValues } from '@livestore/common';
2
+ import { shouldNeverHappen } from '@livestore/utils';
3
+ import { Schema, TreeFormatter } from '@livestore/utils/effect';
4
+ import * as otel from '@opentelemetry/api';
5
+ import { globalReactivityGraph } from '../global-state.js';
6
+ import { NOT_REFRESHED_YET } from '../reactive.js';
7
+ import { getDurationMsFromSpan } from '../utils/otel.js';
8
+ import { LiveStoreQueryBase, makeGetAtomResult } from './base-class.js';
9
+ /**
10
+ * NOTE `querySQL` is only supposed to read data. Don't use it to insert/update/delete data but use mutations instead.
11
+ */
12
+ export const querySQL = (query, options) => new LiveStoreSQLQuery({
13
+ label: options?.label,
14
+ genQueryString: query,
15
+ queriedTables: options?.queriedTables,
16
+ bindValues: options?.bindValues,
17
+ reactivityGraph: options?.reactivityGraph,
18
+ map: options?.map,
19
+ schema: options.schema,
20
+ queryInfo: { _tag: 'None' },
21
+ });
22
+ /* An object encapsulating a reactive SQL query */
23
+ export class LiveStoreSQLQuery extends LiveStoreQueryBase {
24
+ _tag = 'sql';
25
+ /** A reactive thunk representing the query text */
26
+ queryString$;
27
+ /** A reactive thunk representing the query results */
28
+ results$;
29
+ label;
30
+ reactivityGraph;
31
+ /** Currently only used by `rowQuery` for lazy table migrations and eager default row insertion */
32
+ execBeforeFirstRun;
33
+ mapResult;
34
+ schema;
35
+ queryInfo;
36
+ constructor({ genQueryString, queriedTables, bindValues, label = genQueryString.toString(), reactivityGraph, schema, map, execBeforeFirstRun, queryInfo, }) {
37
+ super();
38
+ this.label = `sql(${label})`;
39
+ this.reactivityGraph = reactivityGraph ?? globalReactivityGraph;
40
+ this.execBeforeFirstRun = execBeforeFirstRun;
41
+ this.queryInfo = queryInfo ?? { _tag: 'None' };
42
+ this.schema = schema;
43
+ this.mapResult = map === undefined ? (rows) => rows : map;
44
+ let queryString$OrQueryString;
45
+ if (typeof genQueryString === 'function') {
46
+ queryString$OrQueryString = this.reactivityGraph.makeThunk((get, setDebugInfo, ctx, otelContext) => {
47
+ const startMs = performance.now();
48
+ const queryString = genQueryString(makeGetAtomResult(get, otelContext ?? ctx.rootOtelContext), ctx);
49
+ const durationMs = performance.now() - startMs;
50
+ setDebugInfo({ _tag: 'js', label: `${label}:queryString`, query: queryString, durationMs });
51
+ return queryString;
52
+ }, {
53
+ label: `${label}:queryString`,
54
+ meta: { liveStoreThunkType: 'sqlQueryString' },
55
+ equal: (a, b) => a === b,
56
+ });
57
+ this.queryString$ = queryString$OrQueryString;
58
+ }
59
+ else {
60
+ queryString$OrQueryString = genQueryString;
61
+ }
62
+ const queryLabel = `${label}:results`;
63
+ const queriedTablesRef = { current: queriedTables };
64
+ const schemaEqual = Schema.equivalence(schema);
65
+ // TODO also support derived equality for `map` (probably will depend on having an easy way to transform a schema without an `encode` step)
66
+ // This would mean dropping the `map` option
67
+ const equal = map === undefined
68
+ ? (a, b) => a === NOT_REFRESHED_YET || b === NOT_REFRESHED_YET ? false : schemaEqual(a, b)
69
+ : undefined;
70
+ const results$ = this.reactivityGraph.makeThunk((get, setDebugInfo, { store, otelTracer, rootOtelContext }, otelContext) => otelTracer.startActiveSpan('sql:...', // NOTE span name will be overridden further down
71
+ {}, otelContext ?? rootOtelContext, (span) => {
72
+ const otelContext = otel.trace.setSpan(otel.context.active(), span);
73
+ if (this.execBeforeFirstRun !== undefined) {
74
+ this.execBeforeFirstRun({ store, otelTracer, rootOtelContext, effectsWrapper: (run) => run() });
75
+ this.execBeforeFirstRun = undefined;
76
+ }
77
+ const sqlString = typeof queryString$OrQueryString === 'string'
78
+ ? queryString$OrQueryString
79
+ : get(queryString$OrQueryString, otelContext);
80
+ if (queriedTablesRef.current === undefined) {
81
+ queriedTablesRef.current = store.syncDbWrapper.getTablesUsed(sqlString);
82
+ }
83
+ // Establish a reactive dependency on the tables used in the query
84
+ for (const tableName of queriedTablesRef.current) {
85
+ const tableRef = store.tableRefs[tableName] ?? shouldNeverHappen(`No table ref found for ${tableName}`);
86
+ get(tableRef, otelContext);
87
+ }
88
+ span.setAttribute('sql.query', sqlString);
89
+ span.updateName(`sql:${sqlString.slice(0, 50)}`);
90
+ const rawResults = store.syncDbWrapper.select(sqlString, {
91
+ queriedTables,
92
+ bindValues: bindValues ? prepareBindValues(bindValues, sqlString) : undefined,
93
+ otelContext,
94
+ });
95
+ span.setAttribute('sql.rowsCount', rawResults.length);
96
+ const parsedResult = Schema.decodeEither(this.schema)(rawResults);
97
+ if (parsedResult._tag === 'Left') {
98
+ const parseErrorStr = TreeFormatter.formatErrorSync(parsedResult.left);
99
+ const expectedSchemaStr = String(this.schema.ast);
100
+ const bindValuesStr = bindValues === undefined ? '' : `\nBind values: ${JSON.stringify(bindValues)}`;
101
+ console.error(`\
102
+ Error parsing SQL query result.
103
+
104
+ Query: ${sqlString}\
105
+ ${bindValuesStr}
106
+
107
+ Expected schema: ${expectedSchemaStr}
108
+
109
+ Error: ${parseErrorStr}
110
+
111
+ Result:`, rawResults);
112
+ return shouldNeverHappen(`Error parsing SQL query result: ${parsedResult.left}`);
113
+ }
114
+ const result = this.mapResult(parsedResult.right);
115
+ span.end();
116
+ const durationMs = getDurationMsFromSpan(span);
117
+ this.executionTimes.push(durationMs);
118
+ setDebugInfo({ _tag: 'sql', label, query: sqlString, durationMs });
119
+ return result;
120
+ }), { label: queryLabel, equal });
121
+ this.results$ = results$;
122
+ }
123
+ destroy = () => {
124
+ if (this.queryString$ !== undefined) {
125
+ this.reactivityGraph.destroyNode(this.queryString$);
126
+ }
127
+ this.reactivityGraph.destroyNode(this.results$);
128
+ };
129
+ }
130
+ //# sourceMappingURL=sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/reactiveQueries/sql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sql.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.test.d.ts","sourceRoot":"","sources":["../../src/reactiveQueries/sql.test.ts"],"names":[],"mappings":""}