@livestore/adapter-node 0.3.0-dev.16 → 0.3.0-dev.18
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/client-session/index.d.ts.map +1 -1
- package/dist/client-session/index.js +8 -15
- package/dist/client-session/index.js.map +1 -1
- package/dist/devtools/devtools-server.d.ts.map +1 -1
- package/dist/devtools/devtools-server.js +14 -4
- package/dist/devtools/devtools-server.js.map +1 -1
- package/dist/devtools/vite-dev-server.d.ts.map +1 -1
- package/dist/in-memory/index.d.ts.map +1 -1
- package/dist/in-memory/index.js +9 -5
- package/dist/in-memory/index.js.map +1 -1
- package/dist/make-leader-worker.d.ts +1 -1
- package/dist/make-leader-worker.d.ts.map +1 -1
- package/dist/make-leader-worker.js +7 -2
- package/dist/make-leader-worker.js.map +1 -1
- package/dist/shutdown-channel.d.ts +1 -5
- package/dist/shutdown-channel.d.ts.map +1 -1
- package/dist/webchannel.d.ts.map +1 -1
- package/dist/webchannel.js +3 -3
- package/dist/webchannel.js.map +1 -1
- package/dist/worker-schema.d.ts +2 -2
- package/dist/worker-schema.d.ts.map +1 -1
- package/dist/worker-schema.js +2 -4
- package/dist/worker-schema.js.map +1 -1
- package/package.json +8 -8
- package/src/client-session/index.ts +21 -22
- package/src/devtools/devtools-server.ts +18 -5
- package/src/in-memory/index.ts +22 -4
- package/src/make-leader-worker.ts +10 -3
- package/src/webchannel.ts +11 -8
- package/src/worker-schema.ts +2 -4
- package/tmp/pack.tgz +0 -0
|
@@ -28,10 +28,23 @@ export const startDevtoolsServer = ({
|
|
|
28
28
|
port: number
|
|
29
29
|
}): Effect.Effect<void, UnexpectedError, Scope.Scope> =>
|
|
30
30
|
Effect.gen(function* () {
|
|
31
|
-
const httpServer = http.createServer()
|
|
32
|
-
|
|
31
|
+
const httpServer = yield* Effect.sync(() => http.createServer()).pipe(
|
|
32
|
+
Effect.acquireRelease((httpServer) =>
|
|
33
|
+
Effect.async<void, UnexpectedError>((cb) => {
|
|
34
|
+
httpServer.removeAllListeners()
|
|
35
|
+
httpServer.closeAllConnections()
|
|
36
|
+
httpServer.close((err) => {
|
|
37
|
+
if (err) {
|
|
38
|
+
cb(Effect.fail(UnexpectedError.make({ cause: err })))
|
|
39
|
+
} else {
|
|
40
|
+
cb(Effect.succeed(undefined))
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
}).pipe(Effect.orDie),
|
|
44
|
+
),
|
|
45
|
+
)
|
|
33
46
|
|
|
34
|
-
yield*
|
|
47
|
+
const webSocketServer = yield* makeWebSocketServer({ relayNodeName: 'ws' })
|
|
35
48
|
|
|
36
49
|
// Handle upgrade manually
|
|
37
50
|
httpServer.on('upgrade', (request, socket, head) => {
|
|
@@ -46,7 +59,7 @@ export const startDevtoolsServer = ({
|
|
|
46
59
|
cb(UnexpectedError.make({ cause: err }))
|
|
47
60
|
})
|
|
48
61
|
|
|
49
|
-
httpServer.listen(port, () => {
|
|
62
|
+
httpServer.listen(port, '0.0.0.0', () => {
|
|
50
63
|
cb(Effect.succeed(undefined))
|
|
51
64
|
})
|
|
52
65
|
})
|
|
@@ -54,7 +67,7 @@ export const startDevtoolsServer = ({
|
|
|
54
67
|
yield* startServer(port)
|
|
55
68
|
|
|
56
69
|
yield* Effect.logDebug(
|
|
57
|
-
`[@livestore/adapter-node:devtools] LiveStore devtools are available at http://localhost:${port}/
|
|
70
|
+
`[@livestore/adapter-node:devtools] LiveStore devtools are available at http://localhost:${port}/_livestore`,
|
|
58
71
|
)
|
|
59
72
|
|
|
60
73
|
const viteServer = yield* makeViteServer({
|
package/src/in-memory/index.ts
CHANGED
|
@@ -12,9 +12,11 @@ import type { LiveStoreSchema } from '@livestore/common/schema'
|
|
|
12
12
|
import { MutationEvent } from '@livestore/common/schema'
|
|
13
13
|
import { sqliteDbFactory } from '@livestore/sqlite-wasm/browser'
|
|
14
14
|
import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm'
|
|
15
|
-
import { Effect, FetchHttpClient, Layer, Stream, SubscriptionRef
|
|
15
|
+
import { Cause, Effect, FetchHttpClient, Layer, Stream, SubscriptionRef } from '@livestore/utils/effect'
|
|
16
16
|
import { nanoid } from '@livestore/utils/nanoid'
|
|
17
17
|
|
|
18
|
+
import { makeShutdownChannel } from '../shutdown-channel.js'
|
|
19
|
+
|
|
18
20
|
// TODO unify in-memory adapter with other in-memory adapter implementations
|
|
19
21
|
|
|
20
22
|
export interface InMemoryAdapterOptions {
|
|
@@ -31,6 +33,7 @@ export const makeInMemoryAdapter =
|
|
|
31
33
|
({
|
|
32
34
|
schema,
|
|
33
35
|
storeId,
|
|
36
|
+
shutdown,
|
|
34
37
|
// devtoolsEnabled, bootStatusQueue, shutdown, connectDevtoolsToStore
|
|
35
38
|
}) =>
|
|
36
39
|
Effect.gen(function* () {
|
|
@@ -43,6 +46,17 @@ export const makeInMemoryAdapter =
|
|
|
43
46
|
|
|
44
47
|
const sessionId = nanoid(6)
|
|
45
48
|
|
|
49
|
+
const shutdownChannel = yield* makeShutdownChannel(storeId)
|
|
50
|
+
|
|
51
|
+
yield* shutdownChannel.listen.pipe(
|
|
52
|
+
Stream.flatten(),
|
|
53
|
+
Stream.tap((error) => Effect.sync(() => shutdown(Cause.fail(error)))),
|
|
54
|
+
Stream.runDrain,
|
|
55
|
+
Effect.interruptible,
|
|
56
|
+
Effect.tapCauseLogPretty,
|
|
57
|
+
Effect.forkScoped,
|
|
58
|
+
)
|
|
59
|
+
|
|
46
60
|
const { leaderThread, initialSnapshot } = yield* makeLeaderThread({
|
|
47
61
|
storeId,
|
|
48
62
|
clientId,
|
|
@@ -60,7 +74,7 @@ export const makeInMemoryAdapter =
|
|
|
60
74
|
sessionId,
|
|
61
75
|
lockStatus,
|
|
62
76
|
leaderThread,
|
|
63
|
-
shutdown
|
|
77
|
+
shutdown,
|
|
64
78
|
} satisfies ClientSession
|
|
65
79
|
|
|
66
80
|
return clientSession
|
|
@@ -88,7 +102,8 @@ const makeLeaderThread = ({
|
|
|
88
102
|
devtoolsOptions: { enabled: false },
|
|
89
103
|
makeSqliteDb,
|
|
90
104
|
schema,
|
|
91
|
-
|
|
105
|
+
// NOTE we're creating a separate channel here since you can't listen to your own channel messages
|
|
106
|
+
shutdownChannel: yield* makeShutdownChannel(storeId),
|
|
92
107
|
storeId,
|
|
93
108
|
syncOptions,
|
|
94
109
|
}).pipe(Layer.provideMerge(FetchHttpClient.layer)),
|
|
@@ -112,7 +127,10 @@ const makeLeaderThread = ({
|
|
|
112
127
|
pull: Stream.fromQueue(pullQueue),
|
|
113
128
|
push: (batch) =>
|
|
114
129
|
syncProcessor
|
|
115
|
-
.push(
|
|
130
|
+
.push(
|
|
131
|
+
batch.map((item) => new MutationEvent.EncodedWithMeta(item)),
|
|
132
|
+
{ waitForProcessing: true },
|
|
133
|
+
)
|
|
116
134
|
.pipe(Effect.provide(layer), Effect.scoped),
|
|
117
135
|
},
|
|
118
136
|
initialState: { leaderHead: initialLeaderHead, migrationsReport: initialState.migrationsReport },
|
|
@@ -68,7 +68,11 @@ export const makeWorkerEffect = (options: WorkerOptions) => {
|
|
|
68
68
|
InitialMessage: (args) => makeLeaderThread({ ...args, syncOptions: options.sync }),
|
|
69
69
|
PushToLeader: ({ batch }) =>
|
|
70
70
|
Effect.andThen(LeaderThreadCtx, (_) =>
|
|
71
|
-
_.syncProcessor.push(
|
|
71
|
+
_.syncProcessor.push(
|
|
72
|
+
batch.map((item) => new MutationEvent.EncodedWithMeta(item)),
|
|
73
|
+
// We'll wait in order to keep back pressure on the client session
|
|
74
|
+
{ waitForProcessing: true },
|
|
75
|
+
),
|
|
72
76
|
).pipe(Effect.uninterruptible, Effect.withSpan('@livestore/adapter-node:worker:PushToLeader')),
|
|
73
77
|
BootStatusStream: () =>
|
|
74
78
|
Effect.andThen(LeaderThreadCtx, (_) => Stream.fromQueue(_.bootStatusQueue)).pipe(Stream.unwrap),
|
|
@@ -149,10 +153,13 @@ export const makeWorkerEffect = (options: WorkerOptions) => {
|
|
|
149
153
|
),
|
|
150
154
|
}).pipe(
|
|
151
155
|
Layer.provide(PlatformNode.NodeWorkerRunner.layer),
|
|
152
|
-
|
|
156
|
+
WorkerRunner.launch,
|
|
153
157
|
Effect.scoped,
|
|
154
158
|
Effect.tapCauseLogPretty,
|
|
155
|
-
Effect.annotateLogs({
|
|
159
|
+
Effect.annotateLogs({
|
|
160
|
+
thread: options.otelOptions?.serviceName ?? 'livestore-node-leader-thread',
|
|
161
|
+
processId: process.pid,
|
|
162
|
+
}),
|
|
156
163
|
Effect.provide(Logger.prettyWithThread(options.otelOptions?.serviceName ?? 'livestore-node-leader-thread')),
|
|
157
164
|
Effect.provide(FetchHttpClient.layer),
|
|
158
165
|
Effect.provide(PlatformNode.NodeFileSystem.layer),
|
package/src/webchannel.ts
CHANGED
|
@@ -28,14 +28,17 @@ export const makeBroadcastChannel = <Msg, MsgEncoded>({
|
|
|
28
28
|
// )
|
|
29
29
|
|
|
30
30
|
const listen = Stream.asyncPush<Either.Either<Msg, ParseResult.ParseError>>((emit) =>
|
|
31
|
-
Effect.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
Effect.acquireRelease(
|
|
32
|
+
Effect.gen(function* () {
|
|
33
|
+
// eslint-disable-next-line unicorn/prefer-add-event-listener
|
|
34
|
+
channel.onmessage = (event: any) => {
|
|
35
|
+
return emit.single(Schema.decodeEither(schema)(event.data))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return channel
|
|
39
|
+
}),
|
|
40
|
+
(channel) => Effect.sync(() => channel.unref()),
|
|
41
|
+
),
|
|
39
42
|
)
|
|
40
43
|
|
|
41
44
|
const closedDeferred = yield* Deferred.make<void>().pipe(Effect.acquireRelease(Deferred.done(Exit.void)))
|
package/src/worker-schema.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BootStatus, Devtools,
|
|
1
|
+
import { BootStatus, Devtools, LeaderAheadError, MigrationsReport, SyncState, UnexpectedError } from '@livestore/common'
|
|
2
2
|
import { EventId, MutationEvent } from '@livestore/common/schema'
|
|
3
3
|
import { Schema, Transferable } from '@livestore/utils/effect'
|
|
4
4
|
|
|
@@ -85,8 +85,6 @@ export namespace LeaderWorkerInner {
|
|
|
85
85
|
cursor: EventId.EventId,
|
|
86
86
|
},
|
|
87
87
|
success: Schema.Struct({
|
|
88
|
-
// mutationEvents: Schema.Array(EncodedAny),
|
|
89
|
-
// backendHead: Schema.Number,
|
|
90
88
|
payload: SyncState.PayloadUpstream,
|
|
91
89
|
remaining: Schema.Number,
|
|
92
90
|
}),
|
|
@@ -98,7 +96,7 @@ export namespace LeaderWorkerInner {
|
|
|
98
96
|
batch: Schema.Array(MutationEvent.AnyEncoded),
|
|
99
97
|
},
|
|
100
98
|
success: Schema.Void,
|
|
101
|
-
failure: Schema.Union(UnexpectedError,
|
|
99
|
+
failure: Schema.Union(UnexpectedError, LeaderAheadError),
|
|
102
100
|
}) {}
|
|
103
101
|
|
|
104
102
|
export class Export extends Schema.TaggedRequest<Export>()('Export', {
|
package/tmp/pack.tgz
ADDED
|
Binary file
|