@livestore/livestore 0.2.0-dev.2 → 0.3.0-dev.10

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 (100) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/SynchronousDatabaseWrapper.d.ts +6 -1
  3. package/dist/SynchronousDatabaseWrapper.d.ts.map +1 -1
  4. package/dist/SynchronousDatabaseWrapper.js +14 -2
  5. package/dist/SynchronousDatabaseWrapper.js.map +1 -1
  6. package/dist/__tests__/fixture.d.ts +252 -0
  7. package/dist/__tests__/fixture.d.ts.map +1 -0
  8. package/dist/__tests__/fixture.js +18 -0
  9. package/dist/__tests__/fixture.js.map +1 -0
  10. package/dist/effect/LiveStore.d.ts +6 -6
  11. package/dist/effect/LiveStore.d.ts.map +1 -1
  12. package/dist/effect/LiveStore.js +5 -12
  13. package/dist/effect/LiveStore.js.map +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/live-queries/db.d.ts.map +1 -1
  18. package/dist/live-queries/db.js +28 -23
  19. package/dist/live-queries/db.js.map +1 -1
  20. package/dist/live-queries/db.test.js +2 -1
  21. package/dist/live-queries/db.test.js.map +1 -1
  22. package/dist/row-query-utils.js +1 -1
  23. package/dist/row-query-utils.js.map +1 -1
  24. package/dist/store/create-store.d.ts +12 -10
  25. package/dist/store/create-store.d.ts.map +1 -1
  26. package/dist/store/create-store.js +22 -28
  27. package/dist/store/create-store.js.map +1 -1
  28. package/dist/store/devtools.d.ts +1 -1
  29. package/dist/store/devtools.d.ts.map +1 -1
  30. package/dist/store/devtools.js +41 -19
  31. package/dist/store/devtools.js.map +1 -1
  32. package/dist/store/store-types.d.ts +9 -14
  33. package/dist/store/store-types.d.ts.map +1 -1
  34. package/dist/store/store.d.ts +29 -28
  35. package/dist/store/store.d.ts.map +1 -1
  36. package/dist/store/store.js +147 -160
  37. package/dist/store/store.js.map +1 -1
  38. package/dist/store/store.test.d.ts +2 -0
  39. package/dist/store/store.test.d.ts.map +1 -0
  40. package/dist/store/store.test.js +27 -0
  41. package/dist/store/store.test.js.map +1 -0
  42. package/dist/utils/dev.d.ts.map +1 -1
  43. package/dist/utils/dev.js +3 -2
  44. package/dist/utils/dev.js.map +1 -1
  45. package/dist/utils/tests/fixture.d.ts +1 -1
  46. package/dist/utils/tests/fixture.d.ts.map +1 -1
  47. package/dist/utils/tests/fixture.js +4 -8
  48. package/dist/utils/tests/fixture.js.map +1 -1
  49. package/dist/utils/tests/otel.d.ts +60 -1
  50. package/dist/utils/tests/otel.d.ts.map +1 -1
  51. package/dist/utils/tests/otel.js +65 -4
  52. package/dist/utils/tests/otel.js.map +1 -1
  53. package/package.json +12 -12
  54. package/src/SynchronousDatabaseWrapper.ts +18 -2
  55. package/src/ambient.d.ts +1 -1
  56. package/src/effect/LiveStore.ts +11 -20
  57. package/src/index.ts +1 -1
  58. package/src/live-queries/__snapshots__/db.test.ts.snap +42 -45
  59. package/src/live-queries/db.test.ts +2 -1
  60. package/src/live-queries/db.ts +28 -23
  61. package/src/row-query-utils.ts +1 -1
  62. package/src/store/create-store.ts +115 -119
  63. package/src/store/devtools.ts +48 -22
  64. package/src/store/store-types.ts +14 -14
  65. package/src/store/store.ts +188 -224
  66. package/src/utils/dev.ts +4 -2
  67. package/src/utils/tests/fixture.ts +4 -9
  68. package/src/utils/tests/otel.ts +71 -5
  69. package/dist/live-queries/sql.d.ts +0 -62
  70. package/dist/live-queries/sql.d.ts.map +0 -1
  71. package/dist/live-queries/sql.js +0 -175
  72. package/dist/live-queries/sql.js.map +0 -1
  73. package/dist/live-queries/sql.test.d.ts +0 -2
  74. package/dist/live-queries/sql.test.d.ts.map +0 -1
  75. package/dist/live-queries/sql.test.js +0 -285
  76. package/dist/live-queries/sql.test.js.map +0 -1
  77. package/dist/reactiveQueries/base-class.d.ts +0 -64
  78. package/dist/reactiveQueries/base-class.d.ts.map +0 -1
  79. package/dist/reactiveQueries/base-class.js +0 -31
  80. package/dist/reactiveQueries/base-class.js.map +0 -1
  81. package/dist/reactiveQueries/computed.d.ts +0 -26
  82. package/dist/reactiveQueries/computed.d.ts.map +0 -1
  83. package/dist/reactiveQueries/computed.js +0 -38
  84. package/dist/reactiveQueries/computed.js.map +0 -1
  85. package/dist/reactiveQueries/graphql.d.ts +0 -49
  86. package/dist/reactiveQueries/graphql.d.ts.map +0 -1
  87. package/dist/reactiveQueries/graphql.js +0 -122
  88. package/dist/reactiveQueries/graphql.js.map +0 -1
  89. package/dist/reactiveQueries/sql.d.ts +0 -62
  90. package/dist/reactiveQueries/sql.d.ts.map +0 -1
  91. package/dist/reactiveQueries/sql.js +0 -175
  92. package/dist/reactiveQueries/sql.js.map +0 -1
  93. package/dist/reactiveQueries/sql.test.d.ts +0 -2
  94. package/dist/reactiveQueries/sql.test.d.ts.map +0 -1
  95. package/dist/reactiveQueries/sql.test.js +0 -285
  96. package/dist/reactiveQueries/sql.test.js.map +0 -1
  97. package/dist/row-query.d.ts +0 -16
  98. package/dist/row-query.d.ts.map +0 -1
  99. package/dist/row-query.js +0 -30
  100. package/dist/row-query.js.map +0 -1
@@ -1,7 +1,6 @@
1
1
  import { identity } from '@livestore/utils/effect'
2
2
  import type { Attributes } from '@opentelemetry/api'
3
3
  import type { InMemorySpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base'
4
-
5
4
  type SimplifiedNestedSpan = { _name: string; attributes: any; children: SimplifiedNestedSpan[] }
6
5
 
7
6
  export const getSimplifiedRootSpan = (
@@ -21,27 +20,35 @@ export const getSimplifiedRootSpan = (
21
20
  })
22
21
 
23
22
  type NestedSpan = { span: ReadableSpan; children: NestedSpan[] }
24
- const rootSpan = spansMap.get(spans.find((_) => _.name === 'test')!.spanContext().spanId)!
23
+ const rootSpan = spansMap.get(spans.find((_) => _.name === 'createStore')!.spanContext().spanId)!
25
24
 
26
25
  const simplifySpanRec = (span: NestedSpan): SimplifiedNestedSpan =>
27
26
  omitEmpty({
28
27
  _name: span.span.name,
29
28
  attributes: mapAttributesfn(span.span.attributes),
30
29
  children: span.children
31
- .filter((_) => _.span.name !== 'createStore')
30
+ .filter((_) => _.span.name !== 'createStore:makeAdapter')
32
31
  // .sort((a, b) => compareHrTime(a.span.startTime, b.span.startTime))
33
32
  .map(simplifySpanRec),
34
33
  })
35
34
 
35
+ // console.log('rootSpan', rootSpan.span)
36
+
36
37
  // console.dir(
37
38
  // spans.map((_) => [_.spanContext().spanId, _.name, _.attributes, _.parentSpanId]),
38
39
  // { depth: 10 },
39
40
  // )
40
41
 
41
- return simplifySpanRec(rootSpan)
42
+ const simplifiedRootSpan = simplifySpanRec(rootSpan)
43
+
44
+ // console.log('simplifiedRootSpan', simplifiedRootSpan)
45
+
46
+ // writeFileSync('tmp/trace.json', JSON.stringify(toTraceFile(spans), null, 2))
47
+
48
+ return simplifiedRootSpan
42
49
  }
43
50
 
44
- // const compareHrTime = (a: [number, number], b: [number, number]) => {
51
+ // const compareHrTime = (a: [number, numndber], b: [number, number]) => {
45
52
  // if (a[0] !== b[0]) return a[0] - b[0]
46
53
  // return a[1] - b[1]
47
54
  // }
@@ -59,3 +66,62 @@ const omitEmpty = (obj: any) => {
59
66
  }
60
67
  return result
61
68
  }
69
+
70
+ export const toTraceFile = (spans: ReadableSpan[]) => {
71
+ const hrTimeToBigInt = (hrTime: [number, number]) => (BigInt(hrTime[0]) * BigInt(1e9) + BigInt(hrTime[1])).toString()
72
+ return {
73
+ batches: [
74
+ {
75
+ resource: {
76
+ attributes: [
77
+ {
78
+ key: 'service.name',
79
+ value: {
80
+ stringValue: 'test',
81
+ },
82
+ },
83
+ ],
84
+ droppedAttributesCount: 0,
85
+ },
86
+ instrumentationLibrarySpans: [
87
+ {
88
+ spans: spans.map((span) => ({
89
+ traceId: span.spanContext().traceId,
90
+ spanId: span.spanContext().spanId,
91
+ ...(span.parentSpanId ? { parentSpanId: span.parentSpanId } : {}),
92
+ // traceState: span.spanContext().traceState ?? '',
93
+ name: span.name,
94
+ kind: 'SPAN_KIND_INTERNAL',
95
+ startTimeUnixNano: hrTimeToBigInt(span.startTime),
96
+ endTimeUnixNano: hrTimeToBigInt(span.endTime),
97
+ attributes: Object.entries(span.attributes).map(([key, value]) => ({
98
+ key,
99
+ value:
100
+ typeof value === 'string'
101
+ ? { stringValue: value }
102
+ : typeof value === 'number'
103
+ ? Number.isInteger(value)
104
+ ? { intValue: value }
105
+ : { doubleValue: value }
106
+ : typeof value === 'boolean'
107
+ ? { boolValue: value }
108
+ : { stringValue: JSON.stringify(value) },
109
+ })),
110
+ droppedAttributesCount: span.droppedAttributesCount ?? 0,
111
+ droppedEventsCount: span.droppedEventsCount ?? 0,
112
+ droppedLinksCount: span.droppedLinksCount ?? 0,
113
+ status: {
114
+ code: span.status.code,
115
+ message: span.status.message ?? '',
116
+ },
117
+ })),
118
+ instrumentationLibrary: {
119
+ name: 'livestore',
120
+ version: '',
121
+ },
122
+ },
123
+ ],
124
+ },
125
+ ],
126
+ }
127
+ }
@@ -1,62 +0,0 @@
1
- import type { Bindable, QueryBuilder, QueryInfo } from '@livestore/common';
2
- import { Schema } from '@livestore/utils/effect';
3
- import type { Thunk } from '../reactive.js';
4
- import type { RefreshReason } from '../store/store-types.js';
5
- import type { GetAtomResult, LiveQuery, QueryContext, ReactivityGraph } from './base-class.js';
6
- import { LiveStoreQueryBase } from './base-class.js';
7
- export type QueryInputRaw<TDecoded, TEncoded, TQueryInfo extends QueryInfo> = {
8
- query: string;
9
- schema: Schema.Schema<TDecoded, TEncoded>;
10
- bindValues?: Bindable;
11
- /**
12
- * Can be provided explicitly to slightly speed up initial query performance
13
- *
14
- * NOTE In the future we want to do this automatically at build time
15
- */
16
- queriedTables?: Set<string>;
17
- queryInfo?: TQueryInfo;
18
- execBeforeFirstRun?: (ctx: QueryContext) => void;
19
- };
20
- export type QueryInput<TDecoded, TEncoded, TQueryInfo extends QueryInfo> = QueryInputRaw<TDecoded, TEncoded, TQueryInfo> | QueryBuilder<TDecoded, any, any, TQueryInfo>;
21
- /**
22
- * NOTE `query` is only supposed to read data. Don't use it to insert/update/delete data but use mutations instead.
23
- */
24
- export declare const queryDb: {
25
- <TResultSchema, TResult = TResultSchema, TQueryInfo extends QueryInfo = QueryInfo.None>(queryInput: QueryInputRaw<TResultSchema, ReadonlyArray<any>, TQueryInfo> | QueryBuilder<TResultSchema, any, any, TQueryInfo>, options?: {
26
- map?: (rows: TResultSchema) => TResult;
27
- /**
28
- * Used for debugging / devtools
29
- */
30
- label?: string;
31
- reactivityGraph?: ReactivityGraph;
32
- }): LiveQuery<TResult, TQueryInfo>;
33
- <TResultSchema, TResult = TResultSchema, TQueryInfo extends QueryInfo = QueryInfo.None>(queryInput: ((get: GetAtomResult) => QueryInputRaw<TResultSchema, ReadonlyArray<any>, TQueryInfo>) | ((get: GetAtomResult) => QueryBuilder<TResultSchema, any, any, TQueryInfo>), options?: {
34
- map?: (rows: TResultSchema) => TResult;
35
- /**
36
- * Used for debugging / devtools
37
- */
38
- label?: string;
39
- reactivityGraph?: ReactivityGraph;
40
- queryInfo?: TQueryInfo;
41
- }): LiveQuery<TResult, TQueryInfo>;
42
- };
43
- export declare class LiveStoreDbQuery<TResultSchema, TResult = TResultSchema, TQueryInfo extends QueryInfo = QueryInfo.None> extends LiveStoreQueryBase<TResult, TQueryInfo> {
44
- _tag: 'sql';
45
- /** A reactive thunk representing the query text */
46
- queryInput$: Thunk<QueryInput<TResultSchema, ReadonlyArray<any>, TQueryInfo>, QueryContext, RefreshReason> | undefined;
47
- /** A reactive thunk representing the query results */
48
- results$: Thunk<TResult, QueryContext, RefreshReason>;
49
- label: string;
50
- queryInfo: TQueryInfo;
51
- protected reactivityGraph: ReactivityGraph;
52
- private mapResult;
53
- constructor({ queryInput, label: inputLabel, reactivityGraph, map, queryInfo: queryInfo_, }: {
54
- label?: string;
55
- queryInput: QueryInput<TResultSchema, ReadonlyArray<any>, TQueryInfo> | ((get: GetAtomResult, ctx: QueryContext) => QueryInput<TResultSchema, ReadonlyArray<any>, TQueryInfo>);
56
- reactivityGraph?: ReactivityGraph;
57
- map?: (rows: TResultSchema) => TResult;
58
- queryInfo?: TQueryInfo;
59
- });
60
- destroy: () => void;
61
- }
62
- //# sourceMappingURL=sql.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/live-queries/sql.ts"],"names":[],"mappings":"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"}
@@ -1,175 +0,0 @@
1
- import { getResultSchema, isQueryBuilder, prepareBindValues, QueryBuilderAstSymbol, replaceSessionIdSymbol, } from '@livestore/common';
2
- import { deepEqual, shouldNeverHappen } from '@livestore/utils';
3
- import { Predicate, Schema, TreeFormatter } from '@livestore/utils/effect';
4
- import * as otel from '@opentelemetry/api';
5
- import { globalReactivityGraph } from '../global-state.js';
6
- import { isThunk, NOT_REFRESHED_YET } from '../reactive.js';
7
- import { makeExecBeforeFirstRun, rowQueryLabel } from '../row-query.js';
8
- import { getDurationMsFromSpan } from '../utils/otel.js';
9
- import { LiveStoreQueryBase, makeGetAtomResult } from './base-class.js';
10
- /**
11
- * NOTE `query` is only supposed to read data. Don't use it to insert/update/delete data but use mutations instead.
12
- */
13
- export const queryDb = (queryInput, options) => new LiveStoreDbQuery({
14
- queryInput,
15
- label: options?.label,
16
- reactivityGraph: options?.reactivityGraph,
17
- map: options?.map,
18
- queryInfo: Predicate.hasProperty(options, 'queryInfo') ? options.queryInfo : undefined,
19
- });
20
- /* An object encapsulating a reactive SQL query */
21
- export class LiveStoreDbQuery extends LiveStoreQueryBase {
22
- _tag = 'sql';
23
- /** A reactive thunk representing the query text */
24
- queryInput$;
25
- /** A reactive thunk representing the query results */
26
- results$;
27
- label;
28
- // TODO
29
- queryInfo;
30
- reactivityGraph;
31
- mapResult;
32
- constructor({ queryInput, label: inputLabel, reactivityGraph, map, queryInfo: queryInfo_, }) {
33
- super();
34
- // TODO implement a proper toString method
35
- this.label = inputLabel ? `sql(${inputLabel})` : `sql(${queryInput.toString()})`;
36
- this.reactivityGraph = reactivityGraph ?? globalReactivityGraph;
37
- this.mapResult = map === undefined ? (rows) => rows : map;
38
- const schemaRef = {
39
- current: typeof queryInput === 'function' ? undefined : isQueryBuilder(queryInput) ? undefined : queryInput.schema,
40
- };
41
- const execBeforeFirstRunRef = {
42
- current: undefined,
43
- };
44
- let queryInputRaw$OrQueryInputRaw;
45
- const queryBuilderToQueryInputRaw = (qb) => {
46
- const qbRes = qb.asSql();
47
- const schema = getResultSchema(qb);
48
- const ast = qb[QueryBuilderAstSymbol];
49
- if (ast._tag === 'RowQuery') {
50
- execBeforeFirstRunRef.current = makeExecBeforeFirstRun({
51
- table: ast.tableDef,
52
- insertValues: ast.insertValues,
53
- id: ast.id,
54
- });
55
- this.label = rowQueryLabel(ast.tableDef, ast.id);
56
- }
57
- return {
58
- query: qbRes.query,
59
- schema,
60
- bindValues: qbRes.bindValues,
61
- queriedTables: new Set([ast.tableDef.sqliteDef.name]),
62
- queryInfo: ast._tag === 'RowQuery' ? { _tag: 'Row', table: ast.tableDef, id: ast.id } : { _tag: 'None' },
63
- };
64
- };
65
- if (typeof queryInput === 'function') {
66
- queryInputRaw$OrQueryInputRaw = this.reactivityGraph.makeThunk((get, setDebugInfo, ctx, otelContext) => {
67
- const startMs = performance.now();
68
- const queryInputResult = queryInput(makeGetAtomResult(get, otelContext ?? ctx.rootOtelContext), ctx);
69
- const durationMs = performance.now() - startMs;
70
- const queryInputRaw = isQueryBuilder(queryInputResult)
71
- ? queryBuilderToQueryInputRaw(queryInputResult)
72
- : queryInputResult;
73
- setDebugInfo({ _tag: 'computed', label: `${this.label}:queryInput`, query: queryInputRaw.query, durationMs });
74
- schemaRef.current = queryInputRaw.schema;
75
- this.queryInfo = queryInputRaw.queryInfo;
76
- return queryInputRaw;
77
- }, {
78
- label: `${this.label}:query`,
79
- // TODO adjust to `sqlQueryInput` + adjust in devtools
80
- meta: { liveStoreThunkType: 'sqlQuery' },
81
- // NOTE we're not checking the schema here as we assume the query string to always change when the schema might change
82
- equal: (a, b) => a.query === b.query && deepEqual(a.bindValues, b.bindValues),
83
- });
84
- // TODO come up with a better way to handle this
85
- this.queryInfo = { _tag: 'None' };
86
- }
87
- else {
88
- const queryInputRaw = isQueryBuilder(queryInput) ? queryBuilderToQueryInputRaw(queryInput) : queryInput;
89
- schemaRef.current = queryInputRaw.schema;
90
- queryInputRaw$OrQueryInputRaw = queryInputRaw;
91
- // this.label = inputLabel ? this.label : `sql(${})`
92
- if (inputLabel === undefined && isQueryBuilder(queryInput)) {
93
- const ast = queryInput[QueryBuilderAstSymbol];
94
- if (ast._tag === 'RowQuery') {
95
- this.label = `sql(${rowQueryLabel(ast.tableDef, ast.id)})`;
96
- }
97
- }
98
- this.queryInfo = queryInputRaw.queryInfo;
99
- }
100
- // TODO
101
- const label = this.label;
102
- const queriedTablesRef = { current: undefined };
103
- // const schemaEqual = Schema.equivalence(schema)
104
- // TODO also support derived equality for `map` (probably will depend on having an easy way to transform a schema without an `encode` step)
105
- // This would mean dropping the `map` option
106
- const resultsEqual = map === undefined
107
- ? (a, b) => a === NOT_REFRESHED_YET || b === NOT_REFRESHED_YET ? false : Schema.equivalence(schemaRef.current)(a, b)
108
- : undefined;
109
- const results$ = this.reactivityGraph.makeThunk((get, setDebugInfo, queryContext, otelContext) => queryContext.otelTracer.startActiveSpan('sql:...', // NOTE span name will be overridden further down
110
- {}, otelContext ?? queryContext.rootOtelContext, (span) => {
111
- const otelContext = otel.trace.setSpan(otel.context.active(), span);
112
- const { store } = queryContext;
113
- if (execBeforeFirstRunRef.current !== undefined) {
114
- execBeforeFirstRunRef.current(queryContext, otelContext);
115
- execBeforeFirstRunRef.current = undefined;
116
- }
117
- const queryInputResult = isThunk(queryInputRaw$OrQueryInputRaw)
118
- ? get(queryInputRaw$OrQueryInputRaw, otelContext)
119
- : queryInputRaw$OrQueryInputRaw;
120
- const sqlString = queryInputResult.query;
121
- const bindValues = queryInputResult.bindValues;
122
- if (queriedTablesRef.current === undefined) {
123
- queriedTablesRef.current = store.syncDbWrapper.getTablesUsed(sqlString);
124
- }
125
- if (bindValues !== undefined) {
126
- replaceSessionIdSymbol(bindValues, store.clientSession.coordinator.sessionId);
127
- }
128
- // Establish a reactive dependency on the tables used in the query
129
- for (const tableName of queriedTablesRef.current) {
130
- const tableRef = store.tableRefs[tableName] ?? shouldNeverHappen(`No table ref found for ${tableName}`);
131
- get(tableRef, otelContext);
132
- }
133
- span.setAttribute('sql.query', sqlString);
134
- span.updateName(`sql:${sqlString.slice(0, 50)}`);
135
- const rawDbResults = store.syncDbWrapper.select(sqlString, {
136
- queriedTables: queriedTablesRef.current,
137
- bindValues: bindValues ? prepareBindValues(bindValues, sqlString) : undefined,
138
- otelContext,
139
- });
140
- span.setAttribute('sql.rowsCount', rawDbResults.length);
141
- const parsedResult = Schema.decodeEither(schemaRef.current)(rawDbResults);
142
- if (parsedResult._tag === 'Left') {
143
- const parseErrorStr = TreeFormatter.formatErrorSync(parsedResult.left);
144
- const expectedSchemaStr = String(schemaRef.current.ast);
145
- const bindValuesStr = bindValues === undefined ? '' : `\nBind values: ${JSON.stringify(bindValues)}`;
146
- console.error(`\
147
- Error parsing SQL query result.
148
-
149
- Query: ${sqlString}\
150
- ${bindValuesStr}
151
-
152
- Expected schema: ${expectedSchemaStr}
153
-
154
- Error: ${parseErrorStr}
155
-
156
- Result:`, rawDbResults);
157
- return shouldNeverHappen(`Error parsing SQL query result: ${parsedResult.left}`);
158
- }
159
- const result = this.mapResult(parsedResult.right);
160
- span.end();
161
- const durationMs = getDurationMsFromSpan(span);
162
- this.executionTimes.push(durationMs);
163
- setDebugInfo({ _tag: 'sql', label: `${label}:results`, query: sqlString, durationMs });
164
- return result;
165
- }), { label: `${label}:results`, meta: { liveStoreThunkType: 'sqlResult' }, equal: resultsEqual });
166
- this.results$ = results$;
167
- }
168
- destroy = () => {
169
- if (this.queryInput$ !== undefined) {
170
- this.reactivityGraph.destroyNode(this.queryInput$);
171
- }
172
- this.reactivityGraph.destroyNode(this.results$);
173
- };
174
- }
175
- //# sourceMappingURL=sql.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/live-queries/sql.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=sql.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sql.test.d.ts","sourceRoot":"","sources":["../../src/live-queries/sql.test.ts"],"names":[],"mappings":""}
@@ -1,285 +0,0 @@
1
- import { Effect, Schema } from '@livestore/utils/effect';
2
- import * as otel from '@opentelemetry/api';
3
- import { BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
4
- import { describe, expect, it } from 'vitest';
5
- import { computed, queryDb, rawSqlMutation, sql } from '../index.js';
6
- import { makeTodoMvc, tables } from '../utils/tests/fixture.js';
7
- import { getSimplifiedRootSpan } from '../utils/tests/otel.js';
8
- /*
9
- TODO write tests for:
10
-
11
- - sql queries without and with `map` (incl. callback and schemas)
12
- - optional and explicit `queriedTables` argument
13
- */
14
- describe('otel', () => {
15
- let cachedProvider;
16
- const makeQuery = Effect.gen(function* () {
17
- const exporter = new InMemorySpanExporter();
18
- const provider = cachedProvider ?? new BasicTracerProvider();
19
- cachedProvider = provider;
20
- provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
21
- provider.register();
22
- const otelTracer = otel.trace.getTracer('test');
23
- const span = otelTracer.startSpan('test');
24
- const otelContext = otel.trace.setSpan(otel.context.active(), span);
25
- const { store } = yield* makeTodoMvc({ otelTracer, otelContext });
26
- return {
27
- store,
28
- otelTracer,
29
- exporter,
30
- span,
31
- provider,
32
- };
33
- });
34
- it('otel', async () => {
35
- const { exporter } = await Effect.gen(function* () {
36
- const { store, exporter, span } = yield* makeQuery;
37
- const query$ = queryDb({
38
- query: `select * from todos`,
39
- schema: Schema.Array(tables.todos.schema),
40
- queriedTables: new Set(['todos']),
41
- });
42
- expect(query$.run()).toMatchInlineSnapshot('[]');
43
- store.mutate(rawSqlMutation({ sql: sql `INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)` }));
44
- expect(query$.run()).toMatchInlineSnapshot(`
45
- [
46
- {
47
- "completed": false,
48
- "id": "t1",
49
- "text": "buy milk",
50
- },
51
- ]
52
- `);
53
- query$.destroy();
54
- span.end();
55
- return { exporter };
56
- }).pipe(Effect.scoped, Effect.tapCauseLogPretty, Effect.runPromise);
57
- expect(getSimplifiedRootSpan(exporter)).toMatchInlineSnapshot(`
58
- {
59
- "_name": "test",
60
- "children": [
61
- {
62
- "_name": "livestore.in-memory-db:execute",
63
- "attributes": {
64
- "sql.query": "
65
- PRAGMA page_size=32768;
66
- PRAGMA cache_size=10000;
67
- PRAGMA journal_mode='MEMORY'; -- we don't flush to disk before committing a write
68
- PRAGMA synchronous='OFF';
69
- PRAGMA temp_store='MEMORY';
70
- PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
71
- ",
72
- },
73
- },
74
- {
75
- "_name": "LiveStore:mutations",
76
- "children": [
77
- {
78
- "_name": "LiveStore:mutate",
79
- "attributes": {
80
- "livestore.mutateLabel": "mutate",
81
- },
82
- "children": [
83
- {
84
- "_name": "LiveStore:processWrites",
85
- "attributes": {
86
- "livestore.mutateLabel": "mutate",
87
- },
88
- "children": [
89
- {
90
- "_name": "LiveStore:mutateWithoutRefresh",
91
- "attributes": {
92
- "livestore.args": "{
93
- "sql": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)"
94
- }",
95
- "livestore.mutation": "livestore.RawSql",
96
- },
97
- "children": [
98
- {
99
- "_name": "livestore.in-memory-db:execute",
100
- "attributes": {
101
- "sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
102
- },
103
- },
104
- ],
105
- },
106
- ],
107
- },
108
- ],
109
- },
110
- ],
111
- },
112
- {
113
- "_name": "LiveStore:queries",
114
- "children": [
115
- {
116
- "_name": "sql:select * from todos",
117
- "attributes": {
118
- "sql.query": "select * from todos",
119
- "sql.rowsCount": 0,
120
- },
121
- "children": [
122
- {
123
- "_name": "sql-in-memory-select",
124
- "attributes": {
125
- "sql.cached": false,
126
- "sql.query": "select * from todos",
127
- "sql.rowsCount": 0,
128
- },
129
- },
130
- ],
131
- },
132
- {
133
- "_name": "sql:select * from todos",
134
- "attributes": {
135
- "sql.query": "select * from todos",
136
- "sql.rowsCount": 1,
137
- },
138
- "children": [
139
- {
140
- "_name": "sql-in-memory-select",
141
- "attributes": {
142
- "sql.cached": false,
143
- "sql.query": "select * from todos",
144
- "sql.rowsCount": 1,
145
- },
146
- },
147
- ],
148
- },
149
- ],
150
- },
151
- ],
152
- }
153
- `);
154
- });
155
- it('with thunks', async () => {
156
- const { exporter } = await Effect.gen(function* () {
157
- const { store, exporter, span } = yield* makeQuery;
158
- const defaultTodo = { id: '', text: '', completed: false };
159
- const filter = computed(() => `where completed = 0`, { label: 'where-filter' });
160
- const query$ = queryDb((get) => ({
161
- query: `select * from todos ${get(filter)}`,
162
- schema: Schema.Array(tables.todos.schema).pipe(Schema.headOrElse(() => defaultTodo)),
163
- }), { label: 'all todos' });
164
- expect(query$.run()).toMatchInlineSnapshot(`
165
- {
166
- "completed": false,
167
- "id": "",
168
- "text": "",
169
- }
170
- `);
171
- store.mutate(rawSqlMutation({ sql: sql `INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)` }));
172
- expect(query$.run()).toMatchInlineSnapshot(`
173
- {
174
- "completed": false,
175
- "id": "t1",
176
- "text": "buy milk",
177
- }
178
- `);
179
- query$.destroy();
180
- span.end();
181
- return { exporter };
182
- }).pipe(Effect.scoped, Effect.tapCauseLogPretty, Effect.runPromise);
183
- expect(getSimplifiedRootSpan(exporter)).toMatchInlineSnapshot(`
184
- {
185
- "_name": "test",
186
- "children": [
187
- {
188
- "_name": "livestore.in-memory-db:execute",
189
- "attributes": {
190
- "sql.query": "
191
- PRAGMA page_size=32768;
192
- PRAGMA cache_size=10000;
193
- PRAGMA journal_mode='MEMORY'; -- we don't flush to disk before committing a write
194
- PRAGMA synchronous='OFF';
195
- PRAGMA temp_store='MEMORY';
196
- PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
197
- ",
198
- },
199
- },
200
- {
201
- "_name": "LiveStore:mutations",
202
- "children": [
203
- {
204
- "_name": "LiveStore:mutate",
205
- "attributes": {
206
- "livestore.mutateLabel": "mutate",
207
- },
208
- "children": [
209
- {
210
- "_name": "LiveStore:processWrites",
211
- "attributes": {
212
- "livestore.mutateLabel": "mutate",
213
- },
214
- "children": [
215
- {
216
- "_name": "LiveStore:mutateWithoutRefresh",
217
- "attributes": {
218
- "livestore.args": "{
219
- "sql": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)"
220
- }",
221
- "livestore.mutation": "livestore.RawSql",
222
- },
223
- "children": [
224
- {
225
- "_name": "livestore.in-memory-db:execute",
226
- "attributes": {
227
- "sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
228
- },
229
- },
230
- ],
231
- },
232
- ],
233
- },
234
- ],
235
- },
236
- ],
237
- },
238
- {
239
- "_name": "LiveStore:queries",
240
- "children": [
241
- {
242
- "_name": "sql:select * from todos where completed = 0",
243
- "attributes": {
244
- "sql.query": "select * from todos where completed = 0",
245
- "sql.rowsCount": 0,
246
- },
247
- "children": [
248
- {
249
- "_name": "js:where-filter",
250
- },
251
- {
252
- "_name": "sql-in-memory-select",
253
- "attributes": {
254
- "sql.cached": false,
255
- "sql.query": "select * from todos where completed = 0",
256
- "sql.rowsCount": 0,
257
- },
258
- },
259
- ],
260
- },
261
- {
262
- "_name": "sql:select * from todos where completed = 0",
263
- "attributes": {
264
- "sql.query": "select * from todos where completed = 0",
265
- "sql.rowsCount": 1,
266
- },
267
- "children": [
268
- {
269
- "_name": "sql-in-memory-select",
270
- "attributes": {
271
- "sql.cached": false,
272
- "sql.query": "select * from todos where completed = 0",
273
- "sql.rowsCount": 1,
274
- },
275
- },
276
- ],
277
- },
278
- ],
279
- },
280
- ],
281
- }
282
- `);
283
- });
284
- });
285
- //# sourceMappingURL=sql.test.js.map