@livestore/common 0.0.53 → 0.0.54-dev.1
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/dist/.tsbuildinfo +1 -1
- package/dist/adapter-types.d.ts +8 -0
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +5 -1
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts +36 -0
- package/dist/bounded-collections.d.ts.map +1 -0
- package/dist/bounded-collections.js +98 -0
- package/dist/bounded-collections.js.map +1 -0
- package/dist/debug-info.d.ts +118 -0
- package/dist/debug-info.d.ts.map +1 -0
- package/dist/debug-info.js +50 -0
- package/dist/debug-info.js.map +1 -0
- package/dist/derived-mutations.d.ts +8 -8
- package/dist/devtools/devtools-messages.d.ts +223 -0
- package/dist/devtools/devtools-messages.d.ts.map +1 -0
- package/dist/devtools/devtools-messages.js +148 -0
- package/dist/devtools/devtools-messages.js.map +1 -0
- package/dist/devtools/index copy.d.ts +214 -0
- package/dist/devtools/index copy.d.ts.map +1 -0
- package/dist/devtools/index copy.js +137 -0
- package/dist/devtools/index copy.js.map +1 -0
- package/dist/devtools/index.d.ts +2 -0
- package/dist/devtools/index.d.ts.map +1 -0
- package/dist/devtools/index.js +2 -0
- package/dist/devtools/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schema/index.d.ts +4 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +4 -2
- package/dist/schema/index.js.map +1 -1
- package/dist/util.d.ts +4 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +3 -0
- package/dist/util.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter-types.ts +9 -0
- package/src/bounded-collections.ts +121 -0
- package/src/debug-info.ts +88 -0
- package/src/devtools/devtools-messages.ts +186 -0
- package/src/devtools/index.ts +1 -0
- package/src/index.ts +3 -0
- package/src/schema/index.ts +9 -3
- package/src/util.ts +10 -2
package/dist/util.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/// <reference lib="es2022" />
|
|
2
2
|
import type { Brand } from '@livestore/utils/effect';
|
|
3
|
+
import { Schema } from '@livestore/utils/effect';
|
|
3
4
|
export type ParamsObject = Record<string, SqlValue>;
|
|
4
5
|
export type SqlValue = string | number | Uint8Array | null;
|
|
5
|
-
export type Bindable = SqlValue
|
|
6
|
+
export type Bindable = ReadonlyArray<SqlValue> | ParamsObject;
|
|
7
|
+
export declare const SqlValueSchema: Schema.Union<[typeof Schema.String, typeof Schema.Number, Schema.Schema<Uint8Array, readonly number[], never>, typeof Schema.Null]>;
|
|
8
|
+
export declare const PreparedBindValues: Schema.brand<Schema.Union<[Schema.Array$<Schema.Union<[typeof Schema.String, typeof Schema.Number, Schema.Schema<Uint8Array, readonly number[], never>, typeof Schema.Null]>>, Schema.Record$<typeof Schema.String, Schema.Union<[typeof Schema.String, typeof Schema.Number, Schema.Schema<Uint8Array, readonly number[], never>, typeof Schema.Null]>>]>, "PreparedBindValues">;
|
|
6
9
|
export type PreparedBindValues = Brand.Branded<Bindable, 'PreparedBindValues'>;
|
|
7
10
|
/**
|
|
8
11
|
* This is a tag function for tagged literals.
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AACnD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAAA;AAE1D,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAA;AAE7D,eAAO,MAAM,cAAc,qIAA6E,CAAA;AAExG,eAAO,MAAM,kBAAkB,mXAGW,CAAA;AAE1C,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAA;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,GAAG,aAAc,oBAAoB,WAAW,OAAO,EAAE,KAAG,MASxE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,WAAY,QAAQ,aAAa,MAAM,KAAG,kBAWvE,CAAA"}
|
package/dist/util.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/// <reference lib="es2022" />
|
|
2
|
+
import { Schema } from '@livestore/utils/effect';
|
|
3
|
+
export const SqlValueSchema = Schema.Union(Schema.String, Schema.Number, Schema.Uint8Array, Schema.Null);
|
|
4
|
+
export const PreparedBindValues = Schema.Union(Schema.Array(SqlValueSchema), Schema.Record(Schema.String, SqlValueSchema)).pipe(Schema.brand('PreparedBindValues'));
|
|
2
5
|
/**
|
|
3
6
|
* This is a tag function for tagged literals.
|
|
4
7
|
* it lets us get syntax highlighting on SQL queries in VSCode, but
|
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,8BAA8B;
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAG9B,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAOhD,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;AAExG,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,KAAK,CAC5C,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,EAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAC7C,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAA;AAI1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,QAA8B,EAAE,GAAG,IAAe,EAAU,EAAE;IAChF,IAAI,GAAG,GAAG,EAAE,CAAA;IAEZ,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QACtC,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IAClC,CAAC;IAED,6CAA6C;IAC7C,OAAO,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAC5C,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAgB,EAAE,SAAiB,EAAsB,EAAE;IAC3F,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAAmC,CAAA;IAErE,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,KAAK,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,MAA4B,CAAA;AACrC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/common",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.54-dev.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@opentelemetry/api": "^1.9.0",
|
|
32
|
-
"@livestore/utils": "0.0.
|
|
33
|
-
"effect-db-schema": "0.0.
|
|
32
|
+
"@livestore/utils": "0.0.54-dev.1",
|
|
33
|
+
"effect-db-schema": "0.0.54-dev.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"vitest": "^1.6.0"
|
package/src/adapter-types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Stream, SubscriptionRef, TRef } from '@livestore/utils/effect'
|
|
2
|
+
import { Schema } from '@livestore/utils/effect'
|
|
2
3
|
import type * as otel from '@opentelemetry/api'
|
|
3
4
|
|
|
4
5
|
import type { LiveStoreSchema, MutationEvent } from './schema/index.js'
|
|
@@ -27,12 +28,20 @@ export type InMemoryDatabase = {
|
|
|
27
28
|
|
|
28
29
|
export type ResetMode = 'all-data' | 'only-app-db'
|
|
29
30
|
|
|
31
|
+
export const NetworkStatus = Schema.Struct({
|
|
32
|
+
isConnected: Schema.Boolean,
|
|
33
|
+
timestampMs: Schema.Number,
|
|
34
|
+
})
|
|
35
|
+
|
|
30
36
|
export type NetworkStatus = {
|
|
31
37
|
isConnected: boolean
|
|
32
38
|
timestampMs: number
|
|
33
39
|
}
|
|
34
40
|
|
|
35
41
|
export type Coordinator = {
|
|
42
|
+
devtools: {
|
|
43
|
+
channelId: string
|
|
44
|
+
}
|
|
36
45
|
hasLock: TRef.TRef<boolean>
|
|
37
46
|
syncMutations: Stream.Stream<MutationEvent.AnyEncoded>
|
|
38
47
|
execute(queryStr: string, bindValues: PreparedBindValues | undefined, span: otel.Span | undefined): Promise<void>
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a map that has a fixed number of entries.
|
|
3
|
+
* Once hitting the bound, earliest insertions are removed
|
|
4
|
+
*/
|
|
5
|
+
export class BoundMap<K, V> {
|
|
6
|
+
#map = new Map<K, V>()
|
|
7
|
+
#sizeLimit: number
|
|
8
|
+
|
|
9
|
+
constructor(sizeLimit: number) {
|
|
10
|
+
this.#sizeLimit = sizeLimit
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
onEvict: ((key: K, value: V) => void) | undefined
|
|
14
|
+
|
|
15
|
+
set = (key: K, value: V) => {
|
|
16
|
+
this.#map.set(key, value)
|
|
17
|
+
// console.log(this.#map.size, this.#sizeLimit);
|
|
18
|
+
if (this.#map.size > this.#sizeLimit) {
|
|
19
|
+
const firstKey = this.#map.keys().next().value
|
|
20
|
+
const deletedValue = this.#map.get(firstKey)!
|
|
21
|
+
this.#map.delete(firstKey)
|
|
22
|
+
if (this.onEvict) {
|
|
23
|
+
this.onEvict(firstKey, deletedValue)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get = (key: K): V | undefined => {
|
|
29
|
+
return this.#map.get(key)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
delete = (key: K) => {
|
|
33
|
+
this.#map.delete(key)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
keys = () => {
|
|
37
|
+
return this.#map.keys()
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class BoundSet<V> {
|
|
42
|
+
#map: BoundMap<V, V>
|
|
43
|
+
|
|
44
|
+
constructor(sizeLimit: number) {
|
|
45
|
+
this.#map = new BoundMap(sizeLimit)
|
|
46
|
+
this.#map.onEvict = this.#onEvict
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#onEvict = (v: V) => {
|
|
50
|
+
if (this.onEvict) {
|
|
51
|
+
this.onEvict(v)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
onEvict: ((key: V) => void) | undefined
|
|
56
|
+
|
|
57
|
+
add = (v: V) => {
|
|
58
|
+
this.#map.set(v, v)
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
[Symbol.iterator] = () => {
|
|
62
|
+
return this.#map.keys()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export class BoundArray<V> {
|
|
67
|
+
#array: V[] = []
|
|
68
|
+
public sizeLimit: number
|
|
69
|
+
|
|
70
|
+
constructor(sizeLimit: number) {
|
|
71
|
+
this.sizeLimit = sizeLimit
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static make = <V>(sizeLimit: number, initial: ReadonlyArray<V> = []): BoundArray<V> => {
|
|
75
|
+
const b = new BoundArray<V>(sizeLimit)
|
|
76
|
+
for (const v of initial) {
|
|
77
|
+
b.push(v)
|
|
78
|
+
}
|
|
79
|
+
return b
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
onEvict: ((key: V) => void) | undefined
|
|
83
|
+
|
|
84
|
+
push = (v: V) => {
|
|
85
|
+
this.#array.push(v)
|
|
86
|
+
if (this.#array.length > this.sizeLimit) {
|
|
87
|
+
const first = this.#array.shift()
|
|
88
|
+
if (first && this.onEvict) {
|
|
89
|
+
this.onEvict(first)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get = (index: number): V | undefined => {
|
|
95
|
+
return this.#array[index]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
delete = (index: number) => {
|
|
99
|
+
this.#array.splice(index, 1)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get length() {
|
|
103
|
+
return this.#array.length
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
[Symbol.iterator] = (): IterableIterator<V> => {
|
|
107
|
+
return this.#array[Symbol.iterator]()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
map = <T>(fn: (v: V) => T): T[] => {
|
|
111
|
+
return this.#array.map(fn)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
clear = () => {
|
|
115
|
+
this.#array = []
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
sort = (fn?: (a: V, b: V) => number) => {
|
|
119
|
+
return this.#array.sort(fn)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ParseResult, Schema } from '@livestore/utils/effect'
|
|
2
|
+
|
|
3
|
+
import { BoundArray } from './bounded-collections.js'
|
|
4
|
+
import { PreparedBindValues } from './util.js'
|
|
5
|
+
|
|
6
|
+
export type SlowQueryInfo = {
|
|
7
|
+
queryStr: string
|
|
8
|
+
bindValues: PreparedBindValues | undefined
|
|
9
|
+
durationMs: number
|
|
10
|
+
rowsCount: number | undefined
|
|
11
|
+
queriedTables: Set<string>
|
|
12
|
+
startTimePerfNow: DOMHighResTimeStamp
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const SlowQueryInfo = Schema.Struct({
|
|
16
|
+
queryStr: Schema.String,
|
|
17
|
+
bindValues: Schema.UndefinedOr(PreparedBindValues),
|
|
18
|
+
durationMs: Schema.Number,
|
|
19
|
+
rowsCount: Schema.UndefinedOr(Schema.Number),
|
|
20
|
+
queriedTables: Schema.ReadonlySet(Schema.String),
|
|
21
|
+
startTimePerfNow: Schema.Number,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const BoundArraySchemaFromSelf = <ItemDecoded, ItemEncoded>(_elSchema: Schema.Schema<ItemDecoded, ItemEncoded>) =>
|
|
25
|
+
Schema.declare((_): _ is BoundArray<ItemDecoded> => _ instanceof BoundArray, {
|
|
26
|
+
identifier: `BoundArrayFromSelf`,
|
|
27
|
+
pretty: () => (_) => `BoundArray(${_.length})`,
|
|
28
|
+
arbitrary: () => (fc) => fc.anything() as any,
|
|
29
|
+
equivalence: () => (a, b) => a === b,
|
|
30
|
+
}) as any as Schema.Schema<BoundArray<ItemDecoded>, BoundArray<ItemEncoded>>
|
|
31
|
+
|
|
32
|
+
const BoundArraySchemaFromSelf_ = <A, I, R>(
|
|
33
|
+
item: Schema.Schema<A, I, R>,
|
|
34
|
+
): Schema.Schema<BoundArray<A>, BoundArray<I>, R> =>
|
|
35
|
+
Schema.declare(
|
|
36
|
+
[item],
|
|
37
|
+
{
|
|
38
|
+
decode: (item) => (input, parseOptions, ast) => {
|
|
39
|
+
if (input instanceof BoundArray) {
|
|
40
|
+
const elements = ParseResult.decodeUnknown(Schema.Array(item))([...input], parseOptions)
|
|
41
|
+
return ParseResult.map(elements, (as): BoundArray<A> => BoundArray.make(input.sizeLimit, as))
|
|
42
|
+
}
|
|
43
|
+
return ParseResult.fail(new ParseResult.Type(ast, input))
|
|
44
|
+
},
|
|
45
|
+
encode: (item) => (input, parseOptions, ast) => {
|
|
46
|
+
if (input instanceof BoundArray) {
|
|
47
|
+
const elements = ParseResult.encodeUnknown(Schema.Array(item))([...input], parseOptions)
|
|
48
|
+
return ParseResult.map(elements, (is): BoundArray<I> => BoundArray.make(input.sizeLimit, is))
|
|
49
|
+
}
|
|
50
|
+
return ParseResult.fail(new ParseResult.Type(ast, input))
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
description: `BoundArray<${Schema.format(item)}>`,
|
|
55
|
+
},
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
const BoundArraySchema = <ItemDecoded, ItemEncoded>(elSchema: Schema.Schema<ItemDecoded, ItemEncoded>) =>
|
|
59
|
+
Schema.transform(
|
|
60
|
+
Schema.Struct({
|
|
61
|
+
size: Schema.Number,
|
|
62
|
+
items: Schema.Array(elSchema),
|
|
63
|
+
}),
|
|
64
|
+
BoundArraySchemaFromSelf(elSchema as any as Schema.Schema<ItemDecoded>),
|
|
65
|
+
{
|
|
66
|
+
encode: (_) => ({ size: _.sizeLimit, items: [..._] }),
|
|
67
|
+
decode: (_) => BoundArray.make(_.size, _.items),
|
|
68
|
+
},
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
export const DebugInfo = Schema.Struct({
|
|
72
|
+
slowQueries: BoundArraySchema(SlowQueryInfo),
|
|
73
|
+
queryFrameDuration: Schema.Number,
|
|
74
|
+
queryFrameCount: Schema.Number,
|
|
75
|
+
events: BoundArraySchema(Schema.Tuple(Schema.String, Schema.Any)),
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// export interface DebugInfo {
|
|
79
|
+
// slowQueries: BoundArray<SlowQueryInfo>
|
|
80
|
+
// queryFrameDuration: number
|
|
81
|
+
// queryFrameCount: number
|
|
82
|
+
// events: BoundArray<[queryStr: string, bindValues: Bindable | undefined]>
|
|
83
|
+
// }
|
|
84
|
+
|
|
85
|
+
export type DebugInfo = typeof DebugInfo.Type
|
|
86
|
+
|
|
87
|
+
export const MutableDebugInfo = Schema.mutable(DebugInfo)
|
|
88
|
+
export type MutableDebugInfo = typeof MutableDebugInfo.Type
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { Schema } from '@livestore/utils/effect'
|
|
2
|
+
import { type SqliteDsl as __SqliteDsl } from 'effect-db-schema'
|
|
3
|
+
|
|
4
|
+
import { NetworkStatus } from '../adapter-types.js'
|
|
5
|
+
import { DebugInfo } from '../debug-info.js'
|
|
6
|
+
import { mutationEventSchemaEncodedAny } from '../schema/mutations.js'
|
|
7
|
+
import { PreparedBindValues } from '../util.js'
|
|
8
|
+
|
|
9
|
+
const requestId = Schema.String
|
|
10
|
+
const channelId = Schema.String
|
|
11
|
+
|
|
12
|
+
export class SnapshotReq extends Schema.TaggedStruct('LSD.SnapshotReq', {
|
|
13
|
+
requestId,
|
|
14
|
+
channelId,
|
|
15
|
+
}) {}
|
|
16
|
+
|
|
17
|
+
export class SnapshotRes extends Schema.TaggedStruct('LSD.SnapshotRes', {
|
|
18
|
+
requestId,
|
|
19
|
+
snapshot: Schema.Uint8Array,
|
|
20
|
+
}) {}
|
|
21
|
+
|
|
22
|
+
export class DebugInfoReq extends Schema.TaggedStruct('LSD.DebugInfoReq', {
|
|
23
|
+
requestId,
|
|
24
|
+
channelId,
|
|
25
|
+
}) {}
|
|
26
|
+
|
|
27
|
+
export class DebugInfoRes extends Schema.TaggedStruct('LSD.DebugInfoRes', {
|
|
28
|
+
requestId,
|
|
29
|
+
debugInfo: DebugInfo,
|
|
30
|
+
}) {}
|
|
31
|
+
|
|
32
|
+
export class DebugInfoResetReq extends Schema.TaggedStruct('LSD.DebugInfoResetReq', {
|
|
33
|
+
requestId,
|
|
34
|
+
channelId,
|
|
35
|
+
}) {}
|
|
36
|
+
|
|
37
|
+
export class DebugInfoResetRes extends Schema.TaggedStruct('LSD.DebugInfoResetRes', {
|
|
38
|
+
requestId,
|
|
39
|
+
}) {}
|
|
40
|
+
|
|
41
|
+
export class DebugInfoRerunQueryReq extends Schema.TaggedStruct('LSD.DebugInfoRerunQueryReq', {
|
|
42
|
+
requestId,
|
|
43
|
+
channelId,
|
|
44
|
+
queryStr: Schema.String,
|
|
45
|
+
bindValues: Schema.UndefinedOr(PreparedBindValues),
|
|
46
|
+
queriedTables: Schema.ReadonlySet(Schema.String),
|
|
47
|
+
}) {}
|
|
48
|
+
|
|
49
|
+
export class DebugInfoRerunQueryRes extends Schema.TaggedStruct('LSD.DebugInfoRerunQueryRes', {
|
|
50
|
+
requestId,
|
|
51
|
+
}) {}
|
|
52
|
+
|
|
53
|
+
export class MutationBroadcast extends Schema.TaggedStruct('LSD.MutationBroadcast', {
|
|
54
|
+
requestId,
|
|
55
|
+
mutationEventEncoded: mutationEventSchemaEncodedAny,
|
|
56
|
+
persisted: Schema.Boolean,
|
|
57
|
+
}) {}
|
|
58
|
+
|
|
59
|
+
export class MutationLogReq extends Schema.TaggedStruct('LSD.MutationLogReq', {
|
|
60
|
+
requestId,
|
|
61
|
+
channelId,
|
|
62
|
+
}) {}
|
|
63
|
+
|
|
64
|
+
export class MutationLogRes extends Schema.TaggedStruct('LSD.MutationLogRes', {
|
|
65
|
+
requestId,
|
|
66
|
+
mutationLog: Schema.Uint8Array,
|
|
67
|
+
}) {}
|
|
68
|
+
|
|
69
|
+
export class SignalsSubscribe extends Schema.TaggedStruct('LSD.SignalsSubscribe', {
|
|
70
|
+
requestId,
|
|
71
|
+
channelId,
|
|
72
|
+
includeResults: Schema.Boolean,
|
|
73
|
+
}) {}
|
|
74
|
+
|
|
75
|
+
export class SignalsUnsubscribe extends Schema.TaggedStruct('LSD.SignalsUnsubscribe', {
|
|
76
|
+
requestId,
|
|
77
|
+
channelId,
|
|
78
|
+
}) {}
|
|
79
|
+
|
|
80
|
+
export class SignalsRes extends Schema.TaggedStruct('LSD.SignalsRes', {
|
|
81
|
+
requestId,
|
|
82
|
+
signals: Schema.Any,
|
|
83
|
+
}) {}
|
|
84
|
+
|
|
85
|
+
export class LiveQueriesSubscribe extends Schema.TaggedStruct('LSD.LiveQueriesSubscribe', {
|
|
86
|
+
requestId,
|
|
87
|
+
channelId,
|
|
88
|
+
}) {}
|
|
89
|
+
|
|
90
|
+
export class LiveQueriesUnsubscribe extends Schema.TaggedStruct('LSD.LiveQueriesUnsubscribe', {
|
|
91
|
+
requestId,
|
|
92
|
+
channelId,
|
|
93
|
+
}) {}
|
|
94
|
+
|
|
95
|
+
export class SerializedLiveQuery extends Schema.Struct({
|
|
96
|
+
_tag: Schema.Literal('js', 'sql', 'graphql'),
|
|
97
|
+
id: Schema.Number,
|
|
98
|
+
label: Schema.String,
|
|
99
|
+
runs: Schema.Number,
|
|
100
|
+
executionTimes: Schema.Array(Schema.Number),
|
|
101
|
+
lastestResult: Schema.Any,
|
|
102
|
+
activeSubscriptions: Schema.Array(
|
|
103
|
+
Schema.Struct({ frames: Schema.Array(Schema.Struct({ name: Schema.String, filePath: Schema.String })) }),
|
|
104
|
+
),
|
|
105
|
+
}) {}
|
|
106
|
+
|
|
107
|
+
export class LiveQueriesRes extends Schema.TaggedStruct('LSD.LiveQueriesRes', {
|
|
108
|
+
requestId,
|
|
109
|
+
liveQueries: Schema.Array(SerializedLiveQuery),
|
|
110
|
+
}) {}
|
|
111
|
+
|
|
112
|
+
export class ResetAllDataReq extends Schema.TaggedStruct('LSD.ResetAllDataReq', {
|
|
113
|
+
requestId,
|
|
114
|
+
channelId,
|
|
115
|
+
mode: Schema.Literal('all-data', 'only-app-db'),
|
|
116
|
+
}) {}
|
|
117
|
+
|
|
118
|
+
export class ResetAllDataRes extends Schema.TaggedStruct('LSD.ResetAllDataRes', {
|
|
119
|
+
requestId,
|
|
120
|
+
}) {}
|
|
121
|
+
|
|
122
|
+
export class NetworkStatusBroadcast extends Schema.TaggedStruct('LSD.NetworkStatusBroadcast', {
|
|
123
|
+
channelId,
|
|
124
|
+
networkStatus: NetworkStatus,
|
|
125
|
+
}) {}
|
|
126
|
+
|
|
127
|
+
export class DevtoolsReadyBroadcast extends Schema.TaggedStruct('LSD.DevtoolsReadyBroadcast', {}) {}
|
|
128
|
+
|
|
129
|
+
export class DevtoolsConnected extends Schema.TaggedStruct('LSD.DevtoolsConnected', {
|
|
130
|
+
channelId,
|
|
131
|
+
}) {}
|
|
132
|
+
|
|
133
|
+
export class AppHostReadyBroadcast extends Schema.TaggedStruct('LSD.AppHostReadyBroadcast', {
|
|
134
|
+
channelId,
|
|
135
|
+
}) {}
|
|
136
|
+
|
|
137
|
+
export class Disconnect extends Schema.TaggedStruct('LSD.Disconnect', {
|
|
138
|
+
requestId,
|
|
139
|
+
channelId,
|
|
140
|
+
}) {}
|
|
141
|
+
|
|
142
|
+
// export class SchemaChanged extends Schema.TaggedStruct('LSD.SchemaChanged', {
|
|
143
|
+
// requestId,
|
|
144
|
+
// }) {}
|
|
145
|
+
|
|
146
|
+
export const MessageToAppHost = Schema.Union(
|
|
147
|
+
SnapshotReq,
|
|
148
|
+
MutationLogReq,
|
|
149
|
+
DebugInfoReq,
|
|
150
|
+
DebugInfoResetReq,
|
|
151
|
+
DebugInfoRerunQueryReq,
|
|
152
|
+
SignalsSubscribe,
|
|
153
|
+
SignalsUnsubscribe,
|
|
154
|
+
LiveQueriesSubscribe,
|
|
155
|
+
LiveQueriesUnsubscribe,
|
|
156
|
+
ResetAllDataReq,
|
|
157
|
+
DevtoolsReadyBroadcast,
|
|
158
|
+
Disconnect,
|
|
159
|
+
DevtoolsConnected,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
export type MessageToAppHost = typeof MessageToAppHost.Type
|
|
163
|
+
|
|
164
|
+
export const MessageFromAppHost = Schema.Union(
|
|
165
|
+
SnapshotRes,
|
|
166
|
+
MutationLogRes,
|
|
167
|
+
DebugInfoRes,
|
|
168
|
+
DebugInfoResetRes,
|
|
169
|
+
DebugInfoRerunQueryRes,
|
|
170
|
+
SignalsRes,
|
|
171
|
+
LiveQueriesRes,
|
|
172
|
+
ResetAllDataRes,
|
|
173
|
+
Disconnect,
|
|
174
|
+
// SchemaChanged,
|
|
175
|
+
MutationBroadcast,
|
|
176
|
+
AppHostReadyBroadcast,
|
|
177
|
+
NetworkStatusBroadcast,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
export type MessageFromAppHost = typeof MessageFromAppHost.Type
|
|
181
|
+
|
|
182
|
+
// TODO make specific over app key
|
|
183
|
+
export const makeBroadcastChannels = () => ({
|
|
184
|
+
fromAppHost: new BroadcastChannel(`livestore-devtools-from-app-host`),
|
|
185
|
+
toAppHost: new BroadcastChannel(`livestore-devtools-to-app-host`),
|
|
186
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './devtools-messages.js'
|
package/src/index.ts
CHANGED
|
@@ -8,3 +8,6 @@ export * from './rehydrate-from-mutationlog.js'
|
|
|
8
8
|
export * from './query-info.js'
|
|
9
9
|
export * from './derived-mutations.js'
|
|
10
10
|
export * from './sync/index.js'
|
|
11
|
+
export * as Devtools from './devtools/index.js'
|
|
12
|
+
export * from './debug-info.js'
|
|
13
|
+
export * from './bounded-collections.js'
|
package/src/schema/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isReadonlyArray, shouldNeverHappen } from '@livestore/utils'
|
|
2
2
|
import type { ReadonlyArray } from '@livestore/utils/effect'
|
|
3
|
-
import {
|
|
3
|
+
import type { SqliteDsl } from 'effect-db-schema'
|
|
4
|
+
import { SqliteAst } from 'effect-db-schema'
|
|
4
5
|
|
|
5
6
|
import type { MigrationOptions } from '../adapter-types.js'
|
|
6
7
|
import { makeDerivedMutationDefsForTable } from '../derived-mutations.js'
|
|
@@ -20,10 +21,14 @@ export * as ParseUtils from './parse-utils.js'
|
|
|
20
21
|
export * from './mutations.js'
|
|
21
22
|
export * from './schema-helpers.js'
|
|
22
23
|
|
|
24
|
+
export const LiveStoreSchemaSymbol = Symbol.for('livestore.LiveStoreSchema')
|
|
25
|
+
export type LiveStoreSchemaSymbol = typeof LiveStoreSchemaSymbol
|
|
26
|
+
|
|
23
27
|
export type LiveStoreSchema<
|
|
24
28
|
TDbSchema extends SqliteDsl.DbSchema = SqliteDsl.DbSchema,
|
|
25
29
|
TMutationsDefRecord extends MutationDefRecord = MutationDefRecord,
|
|
26
30
|
> = {
|
|
31
|
+
readonly _Type: LiveStoreSchemaSymbol
|
|
27
32
|
/** Only used on type-level */
|
|
28
33
|
readonly _DbSchemaType: TDbSchema
|
|
29
34
|
/** Only used on type-level */
|
|
@@ -99,8 +104,9 @@ export const makeSchema = <TInputSchema extends InputSchema>(
|
|
|
99
104
|
})
|
|
100
105
|
|
|
101
106
|
return {
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
_Type: LiveStoreSchemaSymbol,
|
|
108
|
+
_DbSchemaType: Symbol.for('livestore.DbSchemaType') as any,
|
|
109
|
+
_MutationDefMapType: Symbol.for('livestore.MutationDefMapType') as any,
|
|
104
110
|
tables,
|
|
105
111
|
mutations,
|
|
106
112
|
migrationOptions: inputSchema.migrations ?? { strategy: 'hard-reset' },
|
package/src/util.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
/// <reference lib="es2022" />
|
|
2
2
|
|
|
3
3
|
import type { Brand } from '@livestore/utils/effect'
|
|
4
|
+
import { Schema } from '@livestore/utils/effect'
|
|
4
5
|
|
|
5
6
|
export type ParamsObject = Record<string, SqlValue>
|
|
6
7
|
export type SqlValue = string | number | Uint8Array | null
|
|
7
8
|
|
|
8
|
-
export type Bindable = SqlValue
|
|
9
|
+
export type Bindable = ReadonlyArray<SqlValue> | ParamsObject
|
|
10
|
+
|
|
11
|
+
export const SqlValueSchema = Schema.Union(Schema.String, Schema.Number, Schema.Uint8Array, Schema.Null)
|
|
12
|
+
|
|
13
|
+
export const PreparedBindValues = Schema.Union(
|
|
14
|
+
Schema.Array(SqlValueSchema),
|
|
15
|
+
Schema.Record(Schema.String, SqlValueSchema),
|
|
16
|
+
).pipe(Schema.brand('PreparedBindValues'))
|
|
9
17
|
|
|
10
18
|
export type PreparedBindValues = Brand.Branded<Bindable, 'PreparedBindValues'>
|
|
11
19
|
|
|
@@ -33,7 +41,7 @@ export const sql = (template: TemplateStringsArray, ...args: unknown[]): string
|
|
|
33
41
|
/* TODO: Search for unused params via proper parsing, not string search
|
|
34
42
|
**/
|
|
35
43
|
export const prepareBindValues = (values: Bindable, statement: string): PreparedBindValues => {
|
|
36
|
-
if (Array.isArray(values)) return values as PreparedBindValues
|
|
44
|
+
if (Array.isArray(values)) return values as any as PreparedBindValues
|
|
37
45
|
|
|
38
46
|
const result: ParamsObject = {}
|
|
39
47
|
for (const [key, value] of Object.entries(values)) {
|