@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.
- package/README.md +1 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/QueryCache.d.ts +20 -0
- package/dist/QueryCache.d.ts.map +1 -0
- package/dist/QueryCache.js +61 -0
- package/dist/QueryCache.js.map +1 -0
- package/dist/SynchronousDatabaseWrapper.d.ts +36 -0
- package/dist/SynchronousDatabaseWrapper.d.ts.map +1 -0
- package/dist/SynchronousDatabaseWrapper.js +176 -0
- package/dist/SynchronousDatabaseWrapper.js.map +1 -0
- package/dist/effect/LiveStore.d.ts +38 -0
- package/dist/effect/LiveStore.d.ts.map +1 -0
- package/dist/effect/LiveStore.js +38 -0
- package/dist/effect/LiveStore.js.map +1 -0
- package/dist/effect/index.d.ts +2 -0
- package/dist/effect/index.d.ts.map +1 -0
- package/dist/effect/index.js +2 -0
- package/dist/effect/index.js.map +1 -0
- package/dist/global-state.d.ts +14 -0
- package/dist/global-state.d.ts.map +1 -0
- package/dist/global-state.js +16 -0
- package/dist/global-state.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/reactive.d.ts +163 -0
- package/dist/reactive.d.ts.map +1 -0
- package/dist/reactive.js +382 -0
- package/dist/reactive.js.map +1 -0
- package/dist/reactive.test.d.ts +2 -0
- package/dist/reactive.test.d.ts.map +1 -0
- package/dist/reactive.test.js +345 -0
- package/dist/reactive.test.js.map +1 -0
- package/dist/reactiveQueries/base-class.d.ts +59 -0
- package/dist/reactiveQueries/base-class.d.ts.map +1 -0
- package/dist/reactiveQueries/base-class.js +29 -0
- package/dist/reactiveQueries/base-class.js.map +1 -0
- package/dist/reactiveQueries/graphql.d.ts +52 -0
- package/dist/reactiveQueries/graphql.d.ts.map +1 -0
- package/dist/reactiveQueries/graphql.js +136 -0
- package/dist/reactiveQueries/graphql.js.map +1 -0
- package/dist/reactiveQueries/js.d.ts +35 -0
- package/dist/reactiveQueries/js.d.ts.map +1 -0
- package/dist/reactiveQueries/js.js +57 -0
- package/dist/reactiveQueries/js.js.map +1 -0
- package/dist/reactiveQueries/sql.d.ts +49 -0
- package/dist/reactiveQueries/sql.d.ts.map +1 -0
- package/dist/reactiveQueries/sql.js +130 -0
- package/dist/reactiveQueries/sql.js.map +1 -0
- package/dist/reactiveQueries/sql.test.d.ts +2 -0
- package/dist/reactiveQueries/sql.test.d.ts.map +1 -0
- package/dist/reactiveQueries/sql.test.js +284 -0
- package/dist/reactiveQueries/sql.test.js.map +1 -0
- package/dist/row-query.d.ts +33 -0
- package/dist/row-query.d.ts.map +1 -0
- package/dist/row-query.js +84 -0
- package/dist/row-query.js.map +1 -0
- package/dist/store-context.d.ts +26 -0
- package/dist/store-context.d.ts.map +1 -0
- package/dist/store-context.js +6 -0
- package/dist/store-context.js.map +1 -0
- package/dist/store-devtools.d.ts +19 -0
- package/dist/store-devtools.d.ts.map +1 -0
- package/dist/store-devtools.js +141 -0
- package/dist/store-devtools.js.map +1 -0
- package/dist/store.d.ts +175 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +507 -0
- package/dist/store.js.map +1 -0
- package/dist/utils/data-structures.d.ts +10 -0
- package/dist/utils/data-structures.d.ts.map +1 -0
- package/dist/utils/data-structures.js +32 -0
- package/dist/utils/data-structures.js.map +1 -0
- package/dist/utils/dev.d.ts +3 -0
- package/dist/utils/dev.d.ts.map +1 -0
- package/dist/utils/dev.js +17 -0
- package/dist/utils/dev.js.map +1 -0
- package/dist/utils/otel.d.ts +4 -0
- package/dist/utils/otel.d.ts.map +1 -0
- package/dist/utils/otel.js +6 -0
- package/dist/utils/otel.js.map +1 -0
- package/dist/utils/stack-info.d.ts +10 -0
- package/dist/utils/stack-info.d.ts.map +1 -0
- package/dist/utils/stack-info.js +41 -0
- package/dist/utils/stack-info.js.map +1 -0
- package/dist/utils/stack-info.test.d.ts +2 -0
- package/dist/utils/stack-info.test.d.ts.map +1 -0
- package/dist/utils/stack-info.test.js +75 -0
- package/dist/utils/stack-info.test.js.map +1 -0
- package/dist/utils/tests/fixture.d.ts +259 -0
- package/dist/utils/tests/fixture.d.ts.map +1 -0
- package/dist/utils/tests/fixture.js +33 -0
- package/dist/utils/tests/fixture.js.map +1 -0
- package/dist/utils/tests/mod.d.ts +3 -0
- package/dist/utils/tests/mod.d.ts.map +1 -0
- package/dist/utils/tests/mod.js +3 -0
- package/dist/utils/tests/mod.js.map +1 -0
- package/dist/utils/tests/otel.d.ts +10 -0
- package/dist/utils/tests/otel.d.ts.map +1 -0
- package/dist/utils/tests/otel.js +42 -0
- package/dist/utils/tests/otel.js.map +1 -0
- package/package.json +60 -0
- package/src/QueryCache.ts +81 -0
- package/src/SynchronousDatabaseWrapper.ts +256 -0
- package/src/ambient.d.ts +10 -0
- package/src/effect/LiveStore.ts +112 -0
- package/src/effect/index.ts +8 -0
- package/src/global-state.ts +20 -0
- package/src/index.ts +64 -0
- package/src/reactive.test.ts +426 -0
- package/src/reactive.ts +661 -0
- package/src/reactiveQueries/base-class.ts +115 -0
- package/src/reactiveQueries/graphql.ts +233 -0
- package/src/reactiveQueries/js.ts +108 -0
- package/src/reactiveQueries/sql.test.ts +308 -0
- package/src/reactiveQueries/sql.ts +226 -0
- package/src/row-query.ts +200 -0
- package/src/store-context.ts +23 -0
- package/src/store-devtools.ts +217 -0
- package/src/store.ts +920 -0
- package/src/utils/data-structures.ts +36 -0
- package/src/utils/dev.ts +24 -0
- package/src/utils/otel.ts +9 -0
- package/src/utils/stack-info.test.ts +79 -0
- package/src/utils/stack-info.ts +54 -0
- package/src/utils/tests/fixture.ts +77 -0
- package/src/utils/tests/mod.ts +2 -0
- package/src/utils/tests/otel.ts +61 -0
- package/tsconfig.json +18 -0
- package/vitest.config.js +9 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// TODO consider replacing with Effect's RC data structures
|
|
2
|
+
export class ReferenceCountedSet<T> {
|
|
3
|
+
private map: Map<T, number>
|
|
4
|
+
|
|
5
|
+
constructor() {
|
|
6
|
+
this.map = new Map<T, number>()
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
add = (key: T) => {
|
|
10
|
+
const count = this.map.get(key) ?? 0
|
|
11
|
+
this.map.set(key, count + 1)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
remove = (key: T) => {
|
|
15
|
+
const count = this.map.get(key) ?? 0
|
|
16
|
+
if (count === 1) {
|
|
17
|
+
this.map.delete(key)
|
|
18
|
+
} else {
|
|
19
|
+
this.map.set(key, count - 1)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
has = (key: T) => {
|
|
24
|
+
return this.map.has(key)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get size() {
|
|
28
|
+
return this.map.size
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
*[Symbol.iterator]() {
|
|
32
|
+
for (const key of this.map.keys()) {
|
|
33
|
+
yield key
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
package/src/utils/dev.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* eslint-disable unicorn/prefer-global-this */
|
|
2
|
+
export const downloadBlob = (
|
|
3
|
+
data: Uint8Array | Blob | string,
|
|
4
|
+
fileName: string,
|
|
5
|
+
mimeType = 'application/octet-stream',
|
|
6
|
+
) => {
|
|
7
|
+
const blob = data instanceof Blob ? data : new Blob([data], { type: mimeType })
|
|
8
|
+
|
|
9
|
+
const url = window.URL.createObjectURL(blob)
|
|
10
|
+
|
|
11
|
+
downloadURL(url, fileName)
|
|
12
|
+
|
|
13
|
+
setTimeout(() => window.URL.revokeObjectURL(url), 1000)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const downloadURL = (data: string, fileName: string) => {
|
|
17
|
+
const a = document.createElement('a')
|
|
18
|
+
a.href = data
|
|
19
|
+
a.download = fileName
|
|
20
|
+
document.body.append(a)
|
|
21
|
+
a.style.display = 'none'
|
|
22
|
+
a.click()
|
|
23
|
+
a.remove()
|
|
24
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as otel from '@opentelemetry/api'
|
|
2
|
+
|
|
3
|
+
export const getDurationMsFromSpan = (span: otel.Span): number => {
|
|
4
|
+
const durationHr: [seconds: number, nanos: number] = (span as any)._duration
|
|
5
|
+
return durationHr[0] * 1000 + durationHr[1] / 1_000_000
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const getStartTimeHighResFromSpan = (span: otel.Span): DOMHighResTimeStamp =>
|
|
9
|
+
(span as any)._performanceStartTime as DOMHighResTimeStamp
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { extractStackInfoFromStackTrace } from './stack-info.js'
|
|
4
|
+
|
|
5
|
+
it('RouteLink stacktrace', async () => {
|
|
6
|
+
const stackTrace = `\
|
|
7
|
+
Error
|
|
8
|
+
at https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1699550216884:18:23
|
|
9
|
+
at mountMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:12817:27)
|
|
10
|
+
at Object.useMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:13141:24)
|
|
11
|
+
at Object.useMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-4WADDZ2G.js?v=3eb66ed6:1094:29)
|
|
12
|
+
at useQuery (https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1699550216884:13:33)
|
|
13
|
+
at useAppState (https://localhost:8081/src/db/AppState.ts?t=1699550216884:17:34)
|
|
14
|
+
at useRoute (https://localhost:8081/src/db/AppState.ts?t=1699550216884:74:22)
|
|
15
|
+
at RouteLink (https://localhost:8081/src/components/Link.tsx?t=1699550216884:36:7)
|
|
16
|
+
at renderWithHooks (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:12171:26)
|
|
17
|
+
at mountIndeterminateComponent (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:14921:21)
|
|
18
|
+
`
|
|
19
|
+
|
|
20
|
+
const stackInfo = extractStackInfoFromStackTrace(stackTrace)
|
|
21
|
+
// Replacing file paths for snapshot testing as they are not stable
|
|
22
|
+
stackInfo.frames.forEach((_) => (_.filePath = '__REPLACED_FOR_SNAPSHOT__'))
|
|
23
|
+
expect(stackInfo).toMatchInlineSnapshot(`
|
|
24
|
+
{
|
|
25
|
+
"frames": [
|
|
26
|
+
{
|
|
27
|
+
"filePath": "__REPLACED_FOR_SNAPSHOT__",
|
|
28
|
+
"name": "RouteLink",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"filePath": "__REPLACED_FOR_SNAPSHOT__",
|
|
32
|
+
"name": "useRoute",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"filePath": "__REPLACED_FOR_SNAPSHOT__",
|
|
36
|
+
"name": "useAppState",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"filePath": "__REPLACED_FOR_SNAPSHOT__",
|
|
40
|
+
"name": "useQuery",
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
}
|
|
44
|
+
`)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('Tracklist_ stacktrace', async () => {
|
|
48
|
+
const stackTrace = `\
|
|
49
|
+
stack Error
|
|
50
|
+
at https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1701368568351:19:23
|
|
51
|
+
at mountMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-YKTDXTVC.js?v=86daed82:12817:27)
|
|
52
|
+
at Object.useMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-YKTDXTVC.js?v=86daed82:13141:24)
|
|
53
|
+
at Object.useMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-7P4K3U7O.js?v=86daed82:1094:29)
|
|
54
|
+
at useQueryRef (https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1701368568351:16:29)
|
|
55
|
+
at Module.useQuery (https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1701368568351:13:36)
|
|
56
|
+
at Tracklist_ (https://localhost:8081/src/components/Tracklist/Tracklist.tsx?t=1701368568351:148:44)
|
|
57
|
+
at renderWithHooks (https://localhost:8081/node_modules/.vite-web/deps/chunk-YKTDXTVC.js?v=86daed82:12171:26)
|
|
58
|
+
at mountIndeterminateComponent (https://localhost:8081/node_modules/.vite-web/deps/chunk-YKTDXTVC.js?v=86daed82:14921:21)
|
|
59
|
+
at beginWork (https://localhost:8081/node_modules/.vite-web/deps/chunk-YKTDXTVC.js?v=86daed82:15902:22)
|
|
60
|
+
`
|
|
61
|
+
|
|
62
|
+
const stackInfo = extractStackInfoFromStackTrace(stackTrace)
|
|
63
|
+
// Replacing file paths for snapshot testing as they are not stable
|
|
64
|
+
stackInfo.frames.forEach((_) => (_.filePath = '__REPLACED_FOR_SNAPSHOT__'))
|
|
65
|
+
expect(stackInfo).toMatchInlineSnapshot(`
|
|
66
|
+
{
|
|
67
|
+
"frames": [
|
|
68
|
+
{
|
|
69
|
+
"filePath": "__REPLACED_FOR_SNAPSHOT__",
|
|
70
|
+
"name": "Tracklist_",
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"filePath": "__REPLACED_FOR_SNAPSHOT__",
|
|
74
|
+
"name": "useQuery",
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
}
|
|
78
|
+
`)
|
|
79
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type StackInfo = {
|
|
2
|
+
frames: StackFrame[]
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export type StackFrame = {
|
|
6
|
+
name: string
|
|
7
|
+
filePath: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
Example stack trace:
|
|
12
|
+
|
|
13
|
+
Error
|
|
14
|
+
at https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1699550216884:18:23
|
|
15
|
+
at mountMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:12817:27)
|
|
16
|
+
at Object.useMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:13141:24)
|
|
17
|
+
at Object.useMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-4WADDZ2G.js?v=3eb66ed6:1094:29)
|
|
18
|
+
at useQuery (https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1699550216884:13:33)
|
|
19
|
+
at useAppState (https://localhost:8081/src/db/AppState.ts?t=1699550216884:17:34)
|
|
20
|
+
at useRoute (https://localhost:8081/src/db/AppState.ts?t=1699550216884:74:22)
|
|
21
|
+
at RouteLink (https://localhost:8081/src/components/Link.tsx?t=1699550216884:36:7)
|
|
22
|
+
at renderWithHooks (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:12171:26)
|
|
23
|
+
at mountIndeterminateComponent (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:14921:21)
|
|
24
|
+
|
|
25
|
+
Approach:
|
|
26
|
+
- Start filtering at `at useQuery` (including)
|
|
27
|
+
- Stop filtering at `at renderWithHooks` (excluding)
|
|
28
|
+
*/
|
|
29
|
+
export const extractStackInfoFromStackTrace = (stackTrace: string): StackInfo => {
|
|
30
|
+
const namePattern = /at (\S+) \((.+)\)/g
|
|
31
|
+
let match: RegExpExecArray | null
|
|
32
|
+
const frames: StackFrame[] = []
|
|
33
|
+
let hasReachedStart = false
|
|
34
|
+
|
|
35
|
+
while ((match = namePattern.exec(stackTrace)) !== null) {
|
|
36
|
+
const [, name, filePath] = match as any as [string, string, string]
|
|
37
|
+
|
|
38
|
+
// NOTE No idea where this `Module.` comes from - possibly a Vite thing?
|
|
39
|
+
if ((name.startsWith('use') || name.startsWith('Module.use')) && name.endsWith('QueryRef') === false) {
|
|
40
|
+
hasReachedStart = true
|
|
41
|
+
|
|
42
|
+
frames.unshift({ name: name.replace(/^Module\./, ''), filePath })
|
|
43
|
+
} else if (hasReachedStart) {
|
|
44
|
+
// We've reached the end of the `use*` functions, so we're adding the component name and stop
|
|
45
|
+
frames.unshift({ name, filePath })
|
|
46
|
+
break
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return { frames }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const stackInfoToString = (stackInfo: StackInfo): string =>
|
|
54
|
+
stackInfo.frames.map((f) => `${f.name} (${f.filePath})`).join('\n')
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { FromInputSchema } from '@livestore/common/schema'
|
|
2
|
+
import type { Store } from '@livestore/livestore'
|
|
3
|
+
import {
|
|
4
|
+
createStore,
|
|
5
|
+
DbSchema,
|
|
6
|
+
globalReactivityGraph,
|
|
7
|
+
makeReactivityGraph,
|
|
8
|
+
makeSchema,
|
|
9
|
+
sql,
|
|
10
|
+
} from '@livestore/livestore'
|
|
11
|
+
import { Effect, FiberSet } from '@livestore/utils/effect'
|
|
12
|
+
import { makeInMemoryAdapter } from '@livestore/web'
|
|
13
|
+
import type * as otel from '@opentelemetry/api'
|
|
14
|
+
|
|
15
|
+
export type Todo = {
|
|
16
|
+
id: string
|
|
17
|
+
text: string
|
|
18
|
+
completed: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type Filter = 'all' | 'active' | 'completed'
|
|
22
|
+
|
|
23
|
+
export type AppState = {
|
|
24
|
+
newTodoText: string
|
|
25
|
+
filter: Filter
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const todos = DbSchema.table(
|
|
29
|
+
'todos',
|
|
30
|
+
{
|
|
31
|
+
id: DbSchema.text({ primaryKey: true }),
|
|
32
|
+
text: DbSchema.text({ default: '', nullable: false }),
|
|
33
|
+
completed: DbSchema.boolean({ default: false, nullable: false }),
|
|
34
|
+
},
|
|
35
|
+
{ deriveMutations: true, isSingleton: false },
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
export const app = DbSchema.table('app', {
|
|
39
|
+
id: DbSchema.text({ primaryKey: true }),
|
|
40
|
+
newTodoText: DbSchema.text({ default: '', nullable: true }),
|
|
41
|
+
filter: DbSchema.text({ default: 'all', nullable: false }),
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
export const tables = { todos, app }
|
|
45
|
+
export const schema = makeSchema({ tables })
|
|
46
|
+
|
|
47
|
+
export interface FixtureSchema extends FromInputSchema.DeriveSchema<{ tables: typeof tables }> {}
|
|
48
|
+
|
|
49
|
+
export const makeTodoMvc = ({
|
|
50
|
+
otelTracer,
|
|
51
|
+
otelContext,
|
|
52
|
+
useGlobalReactivityGraph = true,
|
|
53
|
+
}: {
|
|
54
|
+
otelTracer?: otel.Tracer
|
|
55
|
+
otelContext?: otel.Context
|
|
56
|
+
useGlobalReactivityGraph?: boolean
|
|
57
|
+
} = {}) =>
|
|
58
|
+
Effect.gen(function* () {
|
|
59
|
+
const reactivityGraph = useGlobalReactivityGraph ? globalReactivityGraph : makeReactivityGraph()
|
|
60
|
+
|
|
61
|
+
const fiberSet = yield* FiberSet.make()
|
|
62
|
+
|
|
63
|
+
const store: Store<any, FixtureSchema> = yield* createStore({
|
|
64
|
+
schema,
|
|
65
|
+
storeId: 'default',
|
|
66
|
+
boot: (db) => db.execute(sql`INSERT OR IGNORE INTO app (id, newTodoText, filter) VALUES ('static', '', 'all');`),
|
|
67
|
+
adapter: makeInMemoryAdapter(),
|
|
68
|
+
reactivityGraph,
|
|
69
|
+
otelOptions: {
|
|
70
|
+
tracer: otelTracer,
|
|
71
|
+
rootSpanContext: otelContext,
|
|
72
|
+
},
|
|
73
|
+
fiberSet,
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
return { store, reactivityGraph }
|
|
77
|
+
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { identity } from '@livestore/utils/effect'
|
|
2
|
+
import type { Attributes } from '@opentelemetry/api'
|
|
3
|
+
import type { InMemorySpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base'
|
|
4
|
+
|
|
5
|
+
type SimplifiedNestedSpan = { _name: string; attributes: any; children: SimplifiedNestedSpan[] }
|
|
6
|
+
|
|
7
|
+
export const getSimplifiedRootSpan = (
|
|
8
|
+
exporter: InMemorySpanExporter,
|
|
9
|
+
mapAttributes?: (attributes: Attributes) => Attributes,
|
|
10
|
+
) => {
|
|
11
|
+
const spans = exporter.getFinishedSpans()
|
|
12
|
+
const spansMap = new Map<string, NestedSpan>(spans.map((span) => [span.spanContext().spanId, { span, children: [] }]))
|
|
13
|
+
|
|
14
|
+
const mapAttributesfn = mapAttributes ?? identity
|
|
15
|
+
|
|
16
|
+
spansMap.forEach((nestedSpan) => {
|
|
17
|
+
const parentSpan = nestedSpan.span.parentSpanId ? spansMap.get(nestedSpan.span.parentSpanId) : undefined
|
|
18
|
+
if (parentSpan) {
|
|
19
|
+
parentSpan.children.push(nestedSpan)
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
type NestedSpan = { span: ReadableSpan; children: NestedSpan[] }
|
|
24
|
+
const rootSpan = spansMap.get(spans.find((_) => _.name === 'test')!.spanContext().spanId)!
|
|
25
|
+
|
|
26
|
+
const simplifySpan = (span: NestedSpan): SimplifiedNestedSpan =>
|
|
27
|
+
omitEmpty({
|
|
28
|
+
_name: span.span.name,
|
|
29
|
+
attributes: mapAttributesfn(span.span.attributes),
|
|
30
|
+
children: span.children
|
|
31
|
+
.filter((_) => _.span.name !== 'createStore')
|
|
32
|
+
// .sort((a, b) => compareHrTime(a.span.startTime, b.span.startTime))
|
|
33
|
+
.map(simplifySpan),
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// console.dir(
|
|
37
|
+
// spans.map((_) => [_.spanContext().spanId, _.name, _.attributes, _.parentSpanId]),
|
|
38
|
+
// { depth: 10 },
|
|
39
|
+
// )
|
|
40
|
+
|
|
41
|
+
return simplifySpan(rootSpan)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// const compareHrTime = (a: [number, number], b: [number, number]) => {
|
|
45
|
+
// if (a[0] !== b[0]) return a[0] - b[0]
|
|
46
|
+
// return a[1] - b[1]
|
|
47
|
+
// }
|
|
48
|
+
|
|
49
|
+
const omitEmpty = (obj: any) => {
|
|
50
|
+
const result: any = {}
|
|
51
|
+
for (const key in obj) {
|
|
52
|
+
if (
|
|
53
|
+
obj[key] !== undefined &&
|
|
54
|
+
!(Array.isArray(obj[key]) && obj[key].length === 0) &&
|
|
55
|
+
Object.keys(obj[key]).length > 0
|
|
56
|
+
) {
|
|
57
|
+
result[key] = obj[key]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result
|
|
61
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
// "jsx": "preserve",
|
|
9
|
+
"tsBuildInfoFile": "./dist/.tsbuildinfo"
|
|
10
|
+
},
|
|
11
|
+
"include": ["./src"],
|
|
12
|
+
"references": [
|
|
13
|
+
{ "path": "../db-schema" },
|
|
14
|
+
{ "path": "../common" },
|
|
15
|
+
{ "path": "../web" },
|
|
16
|
+
{ "path": "../utils" }
|
|
17
|
+
]
|
|
18
|
+
}
|