@livestore/devtools-web-common 0.3.0-dev.19 → 0.3.0-dev.22
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/web-channel/index.d.ts +27 -2
- package/dist/web-channel/index.d.ts.map +1 -1
- package/dist/web-channel/index.js +15 -6
- package/dist/web-channel/index.js.map +1 -1
- package/dist/worker/mod.d.ts.map +1 -1
- package/dist/worker/mod.js +3 -4
- package/dist/worker/mod.js.map +1 -1
- package/package.json +4 -8
- package/src/web-channel/index.ts +24 -6
- package/src/worker/mod.ts +3 -4
- package/dist/devtools-bridge/index.d.ts +0 -13
- package/dist/devtools-bridge/index.d.ts.map +0 -1
- package/dist/devtools-bridge/index.js +0 -99
- package/dist/devtools-bridge/index.js.map +0 -1
- package/src/devtools-bridge/index.ts +0 -133
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
import { UnexpectedError } from '@livestore/common';
|
|
2
2
|
import type { Scope, Worker } from '@livestore/utils/effect';
|
|
3
|
-
import { Effect, WebChannel } from '@livestore/utils/effect';
|
|
3
|
+
import { Effect, Schema, WebChannel } from '@livestore/utils/effect';
|
|
4
4
|
import type { MeshNode } from '@livestore/webmesh';
|
|
5
5
|
import * as WorkerSchema from '../worker/schema.js';
|
|
6
|
+
export * as WorkerSchema from '../worker/schema.js';
|
|
7
|
+
declare global {
|
|
8
|
+
var __debugWebmeshNode: any;
|
|
9
|
+
}
|
|
10
|
+
export declare const makeSessionsChannel: Effect.Effect<WebChannel.WebChannel<{
|
|
11
|
+
readonly _tag: "RequestSessions";
|
|
12
|
+
} | {
|
|
13
|
+
readonly _tag: "SessionInfo";
|
|
14
|
+
readonly storeId: string;
|
|
15
|
+
readonly clientId: string;
|
|
16
|
+
readonly sessionId: string;
|
|
17
|
+
}, {
|
|
18
|
+
readonly _tag: "RequestSessions";
|
|
19
|
+
} | {
|
|
20
|
+
readonly _tag: "SessionInfo";
|
|
21
|
+
readonly storeId: string;
|
|
22
|
+
readonly clientId: string;
|
|
23
|
+
readonly sessionId: string;
|
|
24
|
+
}, never>, never, Scope.Scope>;
|
|
25
|
+
export declare const ClientSessionRequestContentscriptMain: Schema.TaggedStruct<"ClientSessionRequestContentscriptMain", {
|
|
26
|
+
storeId: typeof Schema.String;
|
|
27
|
+
clientId: typeof Schema.String;
|
|
28
|
+
sessionId: typeof Schema.String;
|
|
29
|
+
}>;
|
|
30
|
+
export type ClientSessionRequestContentscriptMain = typeof ClientSessionRequestContentscriptMain.Type;
|
|
6
31
|
export declare const makeWebDevtoolsConnectedMeshNode: ({ nodeName, target, worker, }: {
|
|
7
32
|
nodeName: string;
|
|
8
33
|
target: string;
|
|
9
34
|
worker: Worker.SerializedWorkerPool<typeof WorkerSchema.Request.Type>;
|
|
10
|
-
}) => Effect.Effect<MeshNode
|
|
35
|
+
}) => Effect.Effect<MeshNode<string>, UnexpectedError, Scope.Scope>;
|
|
11
36
|
export declare const makeChannelForConnectedMeshNode: <MsgListen, MsgSend, MsgListenEncoded, MsgSendEncoded>({ target, node, schema, }: {
|
|
12
37
|
node: MeshNode;
|
|
13
38
|
target: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web-channel/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web-channel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAE7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAY,MAAM,EAAE,MAAM,EAAU,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAA;AAEnD,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAA;AAEnD,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,kBAAkB,EAAE,GAAG,CAAA;CAC5B;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;8BAG9B,CAAA;AAEF,eAAO,MAAM,qCAAqC;;;;EAIhD,CAAA;AACF,MAAM,MAAM,qCAAqC,GAAG,OAAO,qCAAqC,CAAC,IAAI,CAAA;AAErG,eAAO,MAAM,gCAAgC,GAAI,+BAI9C;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAC,oBAAoB,CAAC,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;CACtE,kEAOG,CAAA;AAEJ,eAAO,MAAM,+BAA+B,GAAI,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,2BAInG;IACD,IAAI,EAAE,QAAQ,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,cAAc,CAAC,CAAA;CACrF,wFAMG,CAAA;AAEJ,eAAO,MAAM,sBAAsB,GAAI,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,yDAM1F;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,cAAc,CAAC,CAAA;IACpF,MAAM,EAAE,MAAM,CAAC,oBAAoB,CAAC,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACrE,gBAAgB,EAAE,MAAM,CAAA;CACzB,KAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,KAAK,CASjB,CAAA;AAExE,eAAO,MAAM,gBAAgB,GAAI,2BAI9B;IACD,IAAI,EAAE,QAAQ,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAC,oBAAoB,CAAC,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;CACtE,sDA+B8C,CAAA"}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import { UnexpectedError } from '@livestore/common';
|
|
1
|
+
import { Devtools, UnexpectedError } from '@livestore/common';
|
|
2
2
|
import { LS_DEV } from '@livestore/utils';
|
|
3
|
-
import { Deferred, Effect, Stream, WebChannel } from '@livestore/utils/effect';
|
|
3
|
+
import { Deferred, Effect, Schema, Stream, WebChannel } from '@livestore/utils/effect';
|
|
4
4
|
import { makeMeshNode, WebmeshSchema } from '@livestore/webmesh';
|
|
5
5
|
import * as WorkerSchema from '../worker/schema.js';
|
|
6
|
+
export * as WorkerSchema from '../worker/schema.js';
|
|
7
|
+
export const makeSessionsChannel = WebChannel.broadcastChannel({
|
|
8
|
+
channelName: 'session-info',
|
|
9
|
+
schema: Devtools.SessionInfo.Message,
|
|
10
|
+
});
|
|
11
|
+
export const ClientSessionRequestContentscriptMain = Schema.TaggedStruct('ClientSessionRequestContentscriptMain', {
|
|
12
|
+
storeId: Schema.String,
|
|
13
|
+
clientId: Schema.String,
|
|
14
|
+
sessionId: Schema.String,
|
|
15
|
+
});
|
|
6
16
|
export const makeWebDevtoolsConnectedMeshNode = ({ nodeName, target, worker, }) => Effect.gen(function* () {
|
|
7
17
|
const node = yield* makeMeshNode(nodeName);
|
|
8
18
|
yield* connectViaWorker({ node, target, worker });
|
|
@@ -10,14 +20,13 @@ export const makeWebDevtoolsConnectedMeshNode = ({ nodeName, target, worker, })
|
|
|
10
20
|
});
|
|
11
21
|
export const makeChannelForConnectedMeshNode = ({ target, node, schema, }) => node.makeChannel({
|
|
12
22
|
target,
|
|
13
|
-
channelName: 'devtools
|
|
23
|
+
channelName: 'devtools(' + [node.nodeName, target].sort().join('↔') + ')',
|
|
14
24
|
schema,
|
|
15
25
|
mode: 'messagechannel',
|
|
16
26
|
});
|
|
17
27
|
export const makeWebDevtoolsChannel = ({ nodeName, target, schema, worker, workerTargetName, }) => Effect.gen(function* () {
|
|
18
28
|
const node = yield* makeWebDevtoolsConnectedMeshNode({ nodeName, target: workerTargetName, worker });
|
|
19
|
-
|
|
20
|
-
globalThis.__debugWebMeshNode = node;
|
|
29
|
+
globalThis.__debugWebmeshNode = node;
|
|
21
30
|
const channel = yield* makeChannelForConnectedMeshNode({ node, target, schema });
|
|
22
31
|
return channel;
|
|
23
32
|
}).pipe(Effect.withSpan(`devtools-web-common:makeWebDevtoolsChannel`));
|
|
@@ -33,7 +42,7 @@ export const connectViaWorker = ({ node, target, worker, }) => Effect.gen(functi
|
|
|
33
42
|
port: mc.port2,
|
|
34
43
|
schema: WebmeshSchema.Packet,
|
|
35
44
|
});
|
|
36
|
-
yield* node.
|
|
45
|
+
yield* node.addEdge({ target, edgeChannel: sharedWorkerConnection, replaceIfExists: true });
|
|
37
46
|
if (LS_DEV) {
|
|
38
47
|
yield* Effect.logDebug(`@livestore/devtools-web-common: initiated connection: ${node.nodeName} → ${target}`);
|
|
39
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/web-channel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/web-channel/index.ts"],"names":[],"mappings":"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"}
|
package/dist/worker/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/worker/mod.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAU,KAAK,EAAE,MAAM,EAAc,MAAM,yBAAyB,CAAA;AACpF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,KAAK,KAAK,kBAAkB,MAAM,aAAa,CAAA;AAEtD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;;UAI3B,QAAQ;;AAFlB,qBAAa,YAAa,SAAQ,iBAG/B;IACD,MAAM,CAAC,KAAK,GAAI,cAAc;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/worker/mod.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAU,KAAK,EAAE,MAAM,EAAc,MAAM,yBAAyB,CAAA;AACpF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,KAAK,KAAK,kBAAkB,MAAM,aAAa,CAAA;AAEtD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;;UAI3B,QAAQ;;AAFlB,qBAAa,YAAa,SAAQ,iBAG/B;IACD,MAAM,CAAC,KAAK,GAAI,cAAc;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,6CAOb;CACtC;AAED,eAAO,MAAM,gBAAgB,GAAI,gBAAgB,OAAO,kBAAkB,CAAC,gBAAgB,CAAC,IAAI,2CAsBJ,CAAA"}
|
package/dist/worker/mod.js
CHANGED
|
@@ -5,20 +5,19 @@ export * as Schema from './schema.js';
|
|
|
5
5
|
export class CacheService extends Context.Tag('@livestore/devtools-web-common:CacheService')() {
|
|
6
6
|
static layer = ({ nodeName }) => Effect.gen(function* () {
|
|
7
7
|
const node = yield* makeMeshNode(nodeName);
|
|
8
|
-
|
|
9
|
-
globalThis.__debugWebMeshNode = node;
|
|
8
|
+
globalThis.__debugWebmeshNode = node;
|
|
10
9
|
return { node };
|
|
11
10
|
}).pipe(Layer.scoped(CacheService));
|
|
12
11
|
}
|
|
13
12
|
export const CreateConnection = ({ from, port }) => Stream.asyncScoped((emit) => Effect.gen(function* () {
|
|
14
13
|
const { node } = yield* CacheService;
|
|
15
14
|
const messagePortChannel = yield* WebChannel.messagePortChannel({ port, schema: WebmeshSchema.Packet });
|
|
16
|
-
yield* node.
|
|
15
|
+
yield* node.addEdge({ target: from, edgeChannel: messagePortChannel, replaceIfExists: true });
|
|
17
16
|
if (LS_DEV) {
|
|
18
17
|
yield* Effect.logDebug(`@livestore/devtools-web-common: accepted connection: ${node.nodeName} ← ${from}`);
|
|
19
18
|
}
|
|
20
19
|
emit.single({});
|
|
21
|
-
yield* Effect.spanEvent({ connectedTo: [...node.
|
|
20
|
+
yield* Effect.spanEvent({ connectedTo: [...node.edgeKeys] });
|
|
22
21
|
// Keep connection alive
|
|
23
22
|
// yield* Effect.never
|
|
24
23
|
// return {}
|
package/dist/worker/mod.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/worker/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAEpF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAIhE,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,MAAM,OAAO,YAAa,SAAQ,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,EAGzF;IACD,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,EAAwB,EAAE,EAAE,CACpD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;QAE1C,
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/worker/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAEpF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAIhE,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,MAAM,OAAO,YAAa,SAAQ,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,EAGzF;IACD,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,EAAwB,EAAE,EAAE,CACpD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;QAE1C,UAAU,CAAC,kBAAkB,GAAG,IAAI,CAAA;QAEpC,OAAO,EAAE,IAAI,EAAE,CAAA;IACjB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAA;;AAGvC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAmD,EAAE,EAAE,CAClG,MAAM,CAAC,WAAW,CAA0B,CAAC,IAAI,EAAE,EAAE,CACnD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,YAAY,CAAA;IAEpC,MAAM,kBAAkB,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAA;IAEvG,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAA;IAE7F,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,wDAAwD,IAAI,CAAC,QAAQ,MAAM,IAAI,EAAE,CAAC,CAAA;IAC3G,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAEf,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAE5D,wBAAwB;IACxB,sBAAsB;IAEtB,YAAY;AACd,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CACtB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,2DAA2D,IAAI,EAAE,CAAC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/devtools-web-common",
|
|
3
|
-
"version": "0.3.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.22",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"exports": {
|
|
@@ -11,16 +11,12 @@
|
|
|
11
11
|
"./worker": {
|
|
12
12
|
"types": "./dist/worker/mod.d.ts",
|
|
13
13
|
"default": "./dist/worker/mod.js"
|
|
14
|
-
},
|
|
15
|
-
"./devtools-bridge": {
|
|
16
|
-
"types": "./dist/devtools-bridge/index.d.ts",
|
|
17
|
-
"default": "./dist/devtools-bridge/index.js"
|
|
18
14
|
}
|
|
19
15
|
},
|
|
20
16
|
"dependencies": {
|
|
21
|
-
"@livestore/common": "0.3.0-dev.
|
|
22
|
-
"@livestore/utils": "0.3.0-dev.
|
|
23
|
-
"@livestore/webmesh": "0.3.0-dev.
|
|
17
|
+
"@livestore/common": "0.3.0-dev.22",
|
|
18
|
+
"@livestore/utils": "0.3.0-dev.22",
|
|
19
|
+
"@livestore/webmesh": "0.3.0-dev.22"
|
|
24
20
|
},
|
|
25
21
|
"devDependencies": {},
|
|
26
22
|
"publishConfig": {
|
package/src/web-channel/index.ts
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
|
-
import { UnexpectedError } from '@livestore/common'
|
|
1
|
+
import { Devtools, UnexpectedError } from '@livestore/common'
|
|
2
2
|
import { LS_DEV } from '@livestore/utils'
|
|
3
3
|
import type { Scope, Worker } from '@livestore/utils/effect'
|
|
4
|
-
import { Deferred, Effect, Stream, WebChannel } from '@livestore/utils/effect'
|
|
4
|
+
import { Deferred, Effect, Schema, Stream, WebChannel } from '@livestore/utils/effect'
|
|
5
5
|
import type { MeshNode } from '@livestore/webmesh'
|
|
6
6
|
import { makeMeshNode, WebmeshSchema } from '@livestore/webmesh'
|
|
7
7
|
|
|
8
8
|
import * as WorkerSchema from '../worker/schema.js'
|
|
9
9
|
|
|
10
|
+
export * as WorkerSchema from '../worker/schema.js'
|
|
11
|
+
|
|
12
|
+
declare global {
|
|
13
|
+
// eslint-disable-next-line no-var
|
|
14
|
+
var __debugWebmeshNode: any
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const makeSessionsChannel = WebChannel.broadcastChannel({
|
|
18
|
+
channelName: 'session-info',
|
|
19
|
+
schema: Devtools.SessionInfo.Message,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
export const ClientSessionRequestContentscriptMain = Schema.TaggedStruct('ClientSessionRequestContentscriptMain', {
|
|
23
|
+
storeId: Schema.String,
|
|
24
|
+
clientId: Schema.String,
|
|
25
|
+
sessionId: Schema.String,
|
|
26
|
+
})
|
|
27
|
+
export type ClientSessionRequestContentscriptMain = typeof ClientSessionRequestContentscriptMain.Type
|
|
28
|
+
|
|
10
29
|
export const makeWebDevtoolsConnectedMeshNode = ({
|
|
11
30
|
nodeName,
|
|
12
31
|
target,
|
|
@@ -35,7 +54,7 @@ export const makeChannelForConnectedMeshNode = <MsgListen, MsgSend, MsgListenEnc
|
|
|
35
54
|
}) =>
|
|
36
55
|
node.makeChannel({
|
|
37
56
|
target,
|
|
38
|
-
channelName: 'devtools
|
|
57
|
+
channelName: 'devtools(' + [node.nodeName, target].sort().join('↔') + ')',
|
|
39
58
|
schema,
|
|
40
59
|
mode: 'messagechannel',
|
|
41
60
|
})
|
|
@@ -56,8 +75,7 @@ export const makeWebDevtoolsChannel = <MsgListen, MsgSend, MsgListenEncoded, Msg
|
|
|
56
75
|
Effect.gen(function* () {
|
|
57
76
|
const node = yield* makeWebDevtoolsConnectedMeshNode({ nodeName, target: workerTargetName, worker })
|
|
58
77
|
|
|
59
|
-
|
|
60
|
-
globalThis.__debugWebMeshNode = node
|
|
78
|
+
globalThis.__debugWebmeshNode = node
|
|
61
79
|
|
|
62
80
|
const channel = yield* makeChannelForConnectedMeshNode({ node, target, schema })
|
|
63
81
|
|
|
@@ -98,7 +116,7 @@ export const connectViaWorker = ({
|
|
|
98
116
|
schema: WebmeshSchema.Packet,
|
|
99
117
|
})
|
|
100
118
|
|
|
101
|
-
yield* node.
|
|
119
|
+
yield* node.addEdge({ target, edgeChannel: sharedWorkerConnection, replaceIfExists: true })
|
|
102
120
|
|
|
103
121
|
if (LS_DEV) {
|
|
104
122
|
yield* Effect.logDebug(`@livestore/devtools-web-common: initiated connection: ${node.nodeName} → ${target}`)
|
package/src/worker/mod.ts
CHANGED
|
@@ -15,8 +15,7 @@ export class CacheService extends Context.Tag('@livestore/devtools-web-common:Ca
|
|
|
15
15
|
Effect.gen(function* () {
|
|
16
16
|
const node = yield* makeMeshNode(nodeName)
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
globalThis.__debugWebMeshNode = node
|
|
18
|
+
globalThis.__debugWebmeshNode = node
|
|
20
19
|
|
|
21
20
|
return { node }
|
|
22
21
|
}).pipe(Layer.scoped(CacheService))
|
|
@@ -29,7 +28,7 @@ export const CreateConnection = ({ from, port }: typeof SharedWorkerSchema.Creat
|
|
|
29
28
|
|
|
30
29
|
const messagePortChannel = yield* WebChannel.messagePortChannel({ port, schema: WebmeshSchema.Packet })
|
|
31
30
|
|
|
32
|
-
yield* node.
|
|
31
|
+
yield* node.addEdge({ target: from, edgeChannel: messagePortChannel, replaceIfExists: true })
|
|
33
32
|
|
|
34
33
|
if (LS_DEV) {
|
|
35
34
|
yield* Effect.logDebug(`@livestore/devtools-web-common: accepted connection: ${node.nodeName} ← ${from}`)
|
|
@@ -37,7 +36,7 @@ export const CreateConnection = ({ from, port }: typeof SharedWorkerSchema.Creat
|
|
|
37
36
|
|
|
38
37
|
emit.single({})
|
|
39
38
|
|
|
40
|
-
yield* Effect.spanEvent({ connectedTo: [...node.
|
|
39
|
+
yield* Effect.spanEvent({ connectedTo: [...node.edgeKeys] })
|
|
41
40
|
|
|
42
41
|
// Keep connection alive
|
|
43
42
|
// yield* Effect.never
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Devtools } from '@livestore/common';
|
|
2
|
-
import type { Scope, Worker } from '@livestore/utils/effect';
|
|
3
|
-
import { Effect } from '@livestore/utils/effect';
|
|
4
|
-
import type * as WorkerSchema from '../worker/schema.js';
|
|
5
|
-
export declare const prepareWebDevtoolsBridge: ({ worker, workerTargetName, storeId, clientId, sessionId, }: {
|
|
6
|
-
worker: Worker.SerializedWorkerPool<typeof WorkerSchema.Request.Type>;
|
|
7
|
-
/** Usually `shared-worker` */
|
|
8
|
-
workerTargetName: string;
|
|
9
|
-
storeId: string;
|
|
10
|
-
clientId: string;
|
|
11
|
-
sessionId: string;
|
|
12
|
-
}) => Effect.Effect<Devtools.PrepareDevtoolsBridge, never, Scope.Scope>;
|
|
13
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/devtools-bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAGhD,OAAO,KAAK,KAAK,YAAY,MAAM,qBAAqB,CAAA;AAIxD,eAAO,MAAM,wBAAwB,GAAI,6DAMtC;IACD,MAAM,EAAE,MAAM,CAAC,oBAAoB,CAAC,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACrE,8BAA8B;IAC9B,gBAAgB,EAAE,MAAM,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB,KAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CA8G7C,CAAA"}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { Devtools } from '@livestore/common';
|
|
2
|
-
import { Effect } from '@livestore/utils/effect';
|
|
3
|
-
import { makeChannelForConnectedMeshNode, makeWebDevtoolsConnectedMeshNode } from '../web-channel/index.js';
|
|
4
|
-
// TODO use a unique bridgeId for each connection (similar to web bridge)
|
|
5
|
-
// TODO refactor the bridge creation code to be re-used for both web and node and possibly expo
|
|
6
|
-
export const prepareWebDevtoolsBridge = ({ worker, workerTargetName, storeId, clientId, sessionId, }) => Effect.gen(function* () {
|
|
7
|
-
const meshNode = yield* makeWebDevtoolsConnectedMeshNode({
|
|
8
|
-
nodeName: `devtools`,
|
|
9
|
-
target: workerTargetName,
|
|
10
|
-
worker,
|
|
11
|
-
});
|
|
12
|
-
// @ts-expect-error typing
|
|
13
|
-
globalThis.__debugWebMeshNode = meshNode;
|
|
14
|
-
const isLeader = true; // TODO properly implement this
|
|
15
|
-
// TODO maybe we need a temporary channel to create a unique bridge channel e..g see appHostInfoDeferred below
|
|
16
|
-
const webDevtoolsChannelStore = yield* makeChannelForConnectedMeshNode({
|
|
17
|
-
node: meshNode,
|
|
18
|
-
target: `client-session-${storeId}-${clientId}-${sessionId}`,
|
|
19
|
-
schema: {
|
|
20
|
-
listen: Devtools.ClientSession.MessageFromApp,
|
|
21
|
-
send: Devtools.ClientSession.MessageToApp,
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
const webDevtoolsChannelCoordinator = yield* makeChannelForConnectedMeshNode({
|
|
25
|
-
node: meshNode,
|
|
26
|
-
target: `leader-${storeId}-${clientId}`,
|
|
27
|
-
schema: { listen: Devtools.Leader.MessageFromApp, send: Devtools.Leader.MessageToApp },
|
|
28
|
-
});
|
|
29
|
-
// const responsePubSub = yield* PubSub.unbounded<
|
|
30
|
-
// Devtools.MessageFromApp | Devtools.MessageFromApp
|
|
31
|
-
// >().pipe(Effect.acquireRelease(PubSub.shutdown))
|
|
32
|
-
// // const appHostInfoDeferred = yield* Deferred.make<{ appHostId: string; isLeader: boolean }>()
|
|
33
|
-
// yield* webDevtoolsChannelCoordinator.listen.pipe(
|
|
34
|
-
// Stream.flatten(),
|
|
35
|
-
// // Stream.tapLogWithLabel('fromCoordinator.listen'),
|
|
36
|
-
// Stream.tap((msg) =>
|
|
37
|
-
// Effect.gen(function* () {
|
|
38
|
-
// yield* PubSub.publish(responsePubSub, msg)
|
|
39
|
-
// }),
|
|
40
|
-
// ),
|
|
41
|
-
// Stream.runDrain,
|
|
42
|
-
// Effect.withSpan('portForDevtoolsChannelCoordinator.listen'),
|
|
43
|
-
// Effect.tapCauseLogPretty,
|
|
44
|
-
// Effect.forkScoped,
|
|
45
|
-
// )
|
|
46
|
-
// yield* webDevtoolsChannelStore.listen.pipe(
|
|
47
|
-
// Stream.flatten(),
|
|
48
|
-
// // Stream.tapLogWithLabel('fromStore.listen'),
|
|
49
|
-
// Stream.tap((msg) =>
|
|
50
|
-
// Effect.gen(function* () {
|
|
51
|
-
// yield* PubSub.publish(responsePubSub, msg)
|
|
52
|
-
// }),
|
|
53
|
-
// ),
|
|
54
|
-
// Stream.runDrain,
|
|
55
|
-
// Effect.withSpan('portForDevtoolsChannelStore.listen'),
|
|
56
|
-
// Effect.tapCauseLogPretty,
|
|
57
|
-
// Effect.forkScoped,
|
|
58
|
-
// )
|
|
59
|
-
// // yield* webDevtoolsChannelCoordinator.send(Devtools.DevtoolsReady.make({ liveStoreVersion }))
|
|
60
|
-
// // const { appHostId, isLeader } = yield* Deferred.await(appHostInfoDeferred)
|
|
61
|
-
// // TODO improve disconnect handling
|
|
62
|
-
// yield* Deferred.await(webDevtoolsChannelCoordinator.closedDeferred).pipe(
|
|
63
|
-
// Effect.tap(() =>
|
|
64
|
-
// PubSub.publish(responsePubSub, Devtools.Disconnect.make({ liveStoreVersion, clientId, sessionId })),
|
|
65
|
-
// ),
|
|
66
|
-
// Effect.tapCauseLogPretty,
|
|
67
|
-
// Effect.forkScoped,
|
|
68
|
-
// )
|
|
69
|
-
// // TODO improve disconnect handling
|
|
70
|
-
// yield* Deferred.await(webDevtoolsChannelStore.closedDeferred).pipe(
|
|
71
|
-
// Effect.tap(() =>
|
|
72
|
-
// PubSub.publish(responsePubSub, Devtools.Disconnect.make({ liveStoreVersion, clientId, sessionId })),
|
|
73
|
-
// ),
|
|
74
|
-
// Effect.tapCauseLogPretty,
|
|
75
|
-
// Effect.forkScoped,
|
|
76
|
-
// )
|
|
77
|
-
// const sendToAppHost: Devtools.PrepareDevtoolsBridge['sendToAppHost'] = (msg) =>
|
|
78
|
-
// Effect.gen(function* () {
|
|
79
|
-
// // NOTE it's possible that a message is for both the coordinator and the store (e.g. Disconnect)
|
|
80
|
-
// if (Schema.is(Devtools.MessageToApp)(msg)) {
|
|
81
|
-
// yield* webDevtoolsChannelCoordinator.send(msg)
|
|
82
|
-
// }
|
|
83
|
-
// if (Schema.is(Devtools.MessageToApp)(msg)) {
|
|
84
|
-
// yield* webDevtoolsChannelStore.send(msg)
|
|
85
|
-
// }
|
|
86
|
-
// }).pipe(Effect.withSpan('sendToAppHost'), Effect.orDie)
|
|
87
|
-
const copyToClipboard = (text) => Effect.sync(() => {
|
|
88
|
-
navigator.clipboard.writeText(text);
|
|
89
|
-
});
|
|
90
|
-
return {
|
|
91
|
-
webchannels: {
|
|
92
|
-
leader: webDevtoolsChannelCoordinator,
|
|
93
|
-
clientSession: webDevtoolsChannelStore,
|
|
94
|
-
},
|
|
95
|
-
clientInfo: { clientId, sessionId, isLeader },
|
|
96
|
-
copyToClipboard,
|
|
97
|
-
};
|
|
98
|
-
}).pipe(Effect.orDie);
|
|
99
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/devtools-bridge/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { Devtools } from '@livestore/common'
|
|
2
|
-
import type { Scope, Worker } from '@livestore/utils/effect'
|
|
3
|
-
import { Effect } from '@livestore/utils/effect'
|
|
4
|
-
|
|
5
|
-
import { makeChannelForConnectedMeshNode, makeWebDevtoolsConnectedMeshNode } from '../web-channel/index.js'
|
|
6
|
-
import type * as WorkerSchema from '../worker/schema.js'
|
|
7
|
-
|
|
8
|
-
// TODO use a unique bridgeId for each connection (similar to web bridge)
|
|
9
|
-
// TODO refactor the bridge creation code to be re-used for both web and node and possibly expo
|
|
10
|
-
export const prepareWebDevtoolsBridge = ({
|
|
11
|
-
worker,
|
|
12
|
-
workerTargetName,
|
|
13
|
-
storeId,
|
|
14
|
-
clientId,
|
|
15
|
-
sessionId,
|
|
16
|
-
}: {
|
|
17
|
-
worker: Worker.SerializedWorkerPool<typeof WorkerSchema.Request.Type>
|
|
18
|
-
/** Usually `shared-worker` */
|
|
19
|
-
workerTargetName: string
|
|
20
|
-
storeId: string
|
|
21
|
-
clientId: string
|
|
22
|
-
sessionId: string
|
|
23
|
-
}): Effect.Effect<Devtools.PrepareDevtoolsBridge, never, Scope.Scope> =>
|
|
24
|
-
Effect.gen(function* () {
|
|
25
|
-
const meshNode = yield* makeWebDevtoolsConnectedMeshNode({
|
|
26
|
-
nodeName: `devtools`,
|
|
27
|
-
target: workerTargetName,
|
|
28
|
-
worker,
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
// @ts-expect-error typing
|
|
32
|
-
globalThis.__debugWebMeshNode = meshNode
|
|
33
|
-
|
|
34
|
-
const isLeader = true // TODO properly implement this
|
|
35
|
-
|
|
36
|
-
// TODO maybe we need a temporary channel to create a unique bridge channel e..g see appHostInfoDeferred below
|
|
37
|
-
const webDevtoolsChannelStore = yield* makeChannelForConnectedMeshNode({
|
|
38
|
-
node: meshNode,
|
|
39
|
-
target: `client-session-${storeId}-${clientId}-${sessionId}`,
|
|
40
|
-
schema: {
|
|
41
|
-
listen: Devtools.ClientSession.MessageFromApp,
|
|
42
|
-
send: Devtools.ClientSession.MessageToApp,
|
|
43
|
-
},
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
const webDevtoolsChannelCoordinator = yield* makeChannelForConnectedMeshNode({
|
|
47
|
-
node: meshNode,
|
|
48
|
-
target: `leader-${storeId}-${clientId}`,
|
|
49
|
-
schema: { listen: Devtools.Leader.MessageFromApp, send: Devtools.Leader.MessageToApp },
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
// const responsePubSub = yield* PubSub.unbounded<
|
|
53
|
-
// Devtools.MessageFromApp | Devtools.MessageFromApp
|
|
54
|
-
// >().pipe(Effect.acquireRelease(PubSub.shutdown))
|
|
55
|
-
|
|
56
|
-
// // const appHostInfoDeferred = yield* Deferred.make<{ appHostId: string; isLeader: boolean }>()
|
|
57
|
-
|
|
58
|
-
// yield* webDevtoolsChannelCoordinator.listen.pipe(
|
|
59
|
-
// Stream.flatten(),
|
|
60
|
-
// // Stream.tapLogWithLabel('fromCoordinator.listen'),
|
|
61
|
-
// Stream.tap((msg) =>
|
|
62
|
-
// Effect.gen(function* () {
|
|
63
|
-
// yield* PubSub.publish(responsePubSub, msg)
|
|
64
|
-
// }),
|
|
65
|
-
// ),
|
|
66
|
-
// Stream.runDrain,
|
|
67
|
-
// Effect.withSpan('portForDevtoolsChannelCoordinator.listen'),
|
|
68
|
-
// Effect.tapCauseLogPretty,
|
|
69
|
-
// Effect.forkScoped,
|
|
70
|
-
// )
|
|
71
|
-
|
|
72
|
-
// yield* webDevtoolsChannelStore.listen.pipe(
|
|
73
|
-
// Stream.flatten(),
|
|
74
|
-
// // Stream.tapLogWithLabel('fromStore.listen'),
|
|
75
|
-
// Stream.tap((msg) =>
|
|
76
|
-
// Effect.gen(function* () {
|
|
77
|
-
// yield* PubSub.publish(responsePubSub, msg)
|
|
78
|
-
// }),
|
|
79
|
-
// ),
|
|
80
|
-
// Stream.runDrain,
|
|
81
|
-
// Effect.withSpan('portForDevtoolsChannelStore.listen'),
|
|
82
|
-
// Effect.tapCauseLogPretty,
|
|
83
|
-
// Effect.forkScoped,
|
|
84
|
-
// )
|
|
85
|
-
|
|
86
|
-
// // yield* webDevtoolsChannelCoordinator.send(Devtools.DevtoolsReady.make({ liveStoreVersion }))
|
|
87
|
-
|
|
88
|
-
// // const { appHostId, isLeader } = yield* Deferred.await(appHostInfoDeferred)
|
|
89
|
-
|
|
90
|
-
// // TODO improve disconnect handling
|
|
91
|
-
// yield* Deferred.await(webDevtoolsChannelCoordinator.closedDeferred).pipe(
|
|
92
|
-
// Effect.tap(() =>
|
|
93
|
-
// PubSub.publish(responsePubSub, Devtools.Disconnect.make({ liveStoreVersion, clientId, sessionId })),
|
|
94
|
-
// ),
|
|
95
|
-
// Effect.tapCauseLogPretty,
|
|
96
|
-
// Effect.forkScoped,
|
|
97
|
-
// )
|
|
98
|
-
|
|
99
|
-
// // TODO improve disconnect handling
|
|
100
|
-
// yield* Deferred.await(webDevtoolsChannelStore.closedDeferred).pipe(
|
|
101
|
-
// Effect.tap(() =>
|
|
102
|
-
// PubSub.publish(responsePubSub, Devtools.Disconnect.make({ liveStoreVersion, clientId, sessionId })),
|
|
103
|
-
// ),
|
|
104
|
-
// Effect.tapCauseLogPretty,
|
|
105
|
-
// Effect.forkScoped,
|
|
106
|
-
// )
|
|
107
|
-
|
|
108
|
-
// const sendToAppHost: Devtools.PrepareDevtoolsBridge['sendToAppHost'] = (msg) =>
|
|
109
|
-
// Effect.gen(function* () {
|
|
110
|
-
// // NOTE it's possible that a message is for both the coordinator and the store (e.g. Disconnect)
|
|
111
|
-
// if (Schema.is(Devtools.MessageToApp)(msg)) {
|
|
112
|
-
// yield* webDevtoolsChannelCoordinator.send(msg)
|
|
113
|
-
// }
|
|
114
|
-
|
|
115
|
-
// if (Schema.is(Devtools.MessageToApp)(msg)) {
|
|
116
|
-
// yield* webDevtoolsChannelStore.send(msg)
|
|
117
|
-
// }
|
|
118
|
-
// }).pipe(Effect.withSpan('sendToAppHost'), Effect.orDie)
|
|
119
|
-
|
|
120
|
-
const copyToClipboard = (text: string) =>
|
|
121
|
-
Effect.sync(() => {
|
|
122
|
-
navigator.clipboard.writeText(text)
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
webchannels: {
|
|
127
|
-
leader: webDevtoolsChannelCoordinator,
|
|
128
|
-
clientSession: webDevtoolsChannelStore,
|
|
129
|
-
},
|
|
130
|
-
clientInfo: { clientId, sessionId, isLeader },
|
|
131
|
-
copyToClipboard,
|
|
132
|
-
} satisfies Devtools.PrepareDevtoolsBridge
|
|
133
|
-
}).pipe(Effect.orDie)
|