@jskit-ai/realtime 0.1.15 → 0.1.17
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/package.descriptor.mjs +5 -3
- package/package.json +3 -5
- package/src/client/RealtimeClientProvider.js +11 -22
- package/src/client/composables/useRealtimeEvent.js +1 -2
- package/src/client/listeners.js +2 -3
- package/src/server/RealtimeServiceProvider.js +22 -28
- package/test/entrypoints.boundary.test.js +0 -11
- package/test/providerRuntime.test.js +20 -30
- package/src/client/tokens.js +0 -11
- package/src/server/tokens.js +0 -7
package/package.descriptor.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
packageVersion: 1,
|
|
3
3
|
packageId: "@jskit-ai/realtime",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.17",
|
|
5
|
+
kind: "runtime",
|
|
5
6
|
description: "Thin, generic realtime runtime wrappers for socket.io server and client.",
|
|
6
7
|
options: {
|
|
7
8
|
"realtime-redis-url": {
|
|
@@ -64,7 +65,8 @@ export default Object.freeze({
|
|
|
64
65
|
],
|
|
65
66
|
containerTokens: {
|
|
66
67
|
server: [
|
|
67
|
-
"runtime.realtime"
|
|
68
|
+
"runtime.realtime",
|
|
69
|
+
"runtime.realtime.io"
|
|
68
70
|
],
|
|
69
71
|
client: [
|
|
70
72
|
"runtime.realtime.client",
|
|
@@ -93,7 +95,7 @@ export default Object.freeze({
|
|
|
93
95
|
mutations: {
|
|
94
96
|
dependencies: {
|
|
95
97
|
runtime: {
|
|
96
|
-
"@jskit-ai/kernel": "0.1.
|
|
98
|
+
"@jskit-ai/kernel": "0.1.18",
|
|
97
99
|
"@socket.io/redis-adapter": "^8.3.0",
|
|
98
100
|
"redis": "^5.8.2",
|
|
99
101
|
"socket.io": "^4.8.3",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/realtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -8,17 +8,15 @@
|
|
|
8
8
|
"exports": {
|
|
9
9
|
"./server/RealtimeServiceProvider": "./src/server/RealtimeServiceProvider.js",
|
|
10
10
|
"./server/runtime": "./src/server/runtime.js",
|
|
11
|
-
"./server/tokens": "./src/server/tokens.js",
|
|
12
11
|
"./client": "./src/client/RealtimeClientProvider.js",
|
|
13
12
|
"./client/RealtimeClientProvider": "./src/client/RealtimeClientProvider.js",
|
|
14
13
|
"./client/listeners": "./src/client/listeners.js",
|
|
15
14
|
"./client/composables/useRealtimeEvent": "./src/client/composables/useRealtimeEvent.js",
|
|
16
|
-
"./client/runtime": "./src/client/runtime.js"
|
|
17
|
-
"./client/tokens": "./src/client/tokens.js"
|
|
15
|
+
"./client/runtime": "./src/client/runtime.js"
|
|
18
16
|
},
|
|
19
17
|
"dependencies": {
|
|
20
18
|
"@socket.io/redis-adapter": "^8.3.0",
|
|
21
|
-
"@jskit-ai/kernel": "0.1.
|
|
19
|
+
"@jskit-ai/kernel": "0.1.18",
|
|
22
20
|
"redis": "^5.8.2",
|
|
23
21
|
"socket.io": "^4.8.3",
|
|
24
22
|
"socket.io-client": "^4.8.3"
|
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
import { createSocketIoClient, disconnectSocketIoClient } from "./runtime.js";
|
|
2
2
|
import { normalizeObject, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
3
|
import { createProviderLogger as createSharedProviderLogger } from "@jskit-ai/kernel/shared/support/providerLogger";
|
|
4
|
-
import {
|
|
5
|
-
CLIENT_MODULE_ENV_TOKEN,
|
|
6
|
-
CLIENT_MODULE_VUE_APP_TOKEN
|
|
7
|
-
} from "@jskit-ai/kernel/client/moduleBootstrap";
|
|
8
4
|
import { resolveClientBootstrapDebugEnabled } from "@jskit-ai/kernel/client";
|
|
9
5
|
import RealtimeConnectionIndicator from "./components/RealtimeConnectionIndicator.js";
|
|
10
|
-
import {
|
|
11
|
-
REALTIME_RUNTIME_CLIENT_TOKEN,
|
|
12
|
-
REALTIME_SOCKET_CLIENT_TOKEN,
|
|
13
|
-
REALTIME_SOCKET_CLIENT_INJECTION_KEY
|
|
14
|
-
} from "./tokens.js";
|
|
15
6
|
import { resolveRealtimeClientListeners } from "./listeners.js";
|
|
16
7
|
|
|
17
|
-
const REALTIME_CONNECTION_INDICATOR_COMPONENT_TOKEN = "realtime.web.connection.indicator";
|
|
18
|
-
|
|
19
8
|
const REALTIME_RUNTIME_CLIENT_API = Object.freeze({
|
|
20
9
|
createSocketIoClient,
|
|
21
10
|
disconnectSocketIoClient
|
|
@@ -23,7 +12,7 @@ const REALTIME_RUNTIME_CLIENT_API = Object.freeze({
|
|
|
23
12
|
|
|
24
13
|
function resolveRealtimeClientConfig(app) {
|
|
25
14
|
const appConfig = app && typeof app.has === "function" && app.has("appConfig") ? normalizeObject(app.make("appConfig")) : {};
|
|
26
|
-
const env = app && typeof app.has === "function" && app.has(
|
|
15
|
+
const env = app && typeof app.has === "function" && app.has("jskit.client.env") ? normalizeObject(app.make("jskit.client.env")) : {};
|
|
27
16
|
const realtime = normalizeObject(appConfig.realtime);
|
|
28
17
|
const realtimeClient = normalizeObject(appConfig.realtimeClient);
|
|
29
18
|
const url = normalizeText(realtimeClient.url);
|
|
@@ -55,17 +44,17 @@ function resolveRealtimeClientConfig(app) {
|
|
|
55
44
|
}
|
|
56
45
|
|
|
57
46
|
class RealtimeClientProvider {
|
|
58
|
-
static id =
|
|
47
|
+
static id = "runtime.realtime.client";
|
|
59
48
|
|
|
60
49
|
register(app) {
|
|
61
50
|
if (!app || typeof app.singleton !== "function") {
|
|
62
51
|
throw new Error("RealtimeClientProvider requires application singleton().");
|
|
63
52
|
}
|
|
64
53
|
|
|
65
|
-
app.singleton(
|
|
66
|
-
app.singleton(
|
|
67
|
-
app.singleton(
|
|
68
|
-
const realtimeRuntime = scope.make(
|
|
54
|
+
app.singleton("runtime.realtime.client", () => REALTIME_RUNTIME_CLIENT_API);
|
|
55
|
+
app.singleton("realtime.web.connection.indicator", () => RealtimeConnectionIndicator);
|
|
56
|
+
app.singleton("runtime.realtime.client.socket", (scope) => {
|
|
57
|
+
const realtimeRuntime = scope.make("runtime.realtime.client");
|
|
69
58
|
const realtimeClientConfig = resolveRealtimeClientConfig(scope);
|
|
70
59
|
return realtimeRuntime.createSocketIoClient({
|
|
71
60
|
url: realtimeClientConfig.url,
|
|
@@ -83,7 +72,7 @@ class RealtimeClientProvider {
|
|
|
83
72
|
const logger = createSharedProviderLogger(app, {
|
|
84
73
|
debugEnabled: realtimeClientConfig.debugEnabled
|
|
85
74
|
});
|
|
86
|
-
const socket = app.make(
|
|
75
|
+
const socket = app.make("runtime.realtime.client.socket");
|
|
87
76
|
const listeners = resolveRealtimeClientListeners(app);
|
|
88
77
|
const detach = [];
|
|
89
78
|
|
|
@@ -230,15 +219,15 @@ class RealtimeClientProvider {
|
|
|
230
219
|
this.socket = socket;
|
|
231
220
|
this.detach = detach;
|
|
232
221
|
|
|
233
|
-
if (!app.has(
|
|
222
|
+
if (!app.has("jskit.client.vue.app")) {
|
|
234
223
|
return;
|
|
235
224
|
}
|
|
236
225
|
|
|
237
|
-
const vueApp = app.make(
|
|
226
|
+
const vueApp = app.make("jskit.client.vue.app");
|
|
238
227
|
if (!vueApp || typeof vueApp.provide !== "function") {
|
|
239
228
|
return;
|
|
240
229
|
}
|
|
241
|
-
vueApp.provide(
|
|
230
|
+
vueApp.provide("jskit.realtime.runtime.client.socket", socket);
|
|
242
231
|
}
|
|
243
232
|
|
|
244
233
|
shutdown(app) {
|
|
@@ -258,7 +247,7 @@ class RealtimeClientProvider {
|
|
|
258
247
|
}
|
|
259
248
|
|
|
260
249
|
const runtimeApi =
|
|
261
|
-
app && typeof app.make === "function" ? app.make(
|
|
250
|
+
app && typeof app.make === "function" ? app.make("runtime.realtime.client") : REALTIME_RUNTIME_CLIENT_API;
|
|
262
251
|
runtimeApi.disconnectSocketIoClient(this.socket);
|
|
263
252
|
this.socket = null;
|
|
264
253
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { inject, onBeforeUnmount, ref, unref, watch } from "vue";
|
|
2
2
|
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
|
-
import { REALTIME_SOCKET_CLIENT_INJECTION_KEY } from "../tokens.js";
|
|
4
3
|
|
|
5
4
|
const EMPTY_REALTIME_SOCKET = Object.freeze({
|
|
6
5
|
on() {},
|
|
@@ -31,7 +30,7 @@ function resolveEventName(value) {
|
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
function useRealtimeSocket({ required = false } = {}) {
|
|
34
|
-
const socket = inject(
|
|
33
|
+
const socket = inject("jskit.realtime.runtime.client.socket", null);
|
|
35
34
|
if (isRealtimeSocket(socket)) {
|
|
36
35
|
return socket;
|
|
37
36
|
}
|
package/src/client/listeners.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
2
|
-
import { REALTIME_CLIENT_LISTENER_TAG } from "./tokens.js";
|
|
3
2
|
|
|
4
3
|
function normalizeListenerEntries(value) {
|
|
5
4
|
const queue = Array.isArray(value) ? [...value] : [value];
|
|
@@ -49,7 +48,7 @@ function registerRealtimeClientListener(app, token, factory) {
|
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
app.singleton(token, factory);
|
|
52
|
-
app.tag(token,
|
|
51
|
+
app.tag(token, "jskit.runtime.realtime.client.listeners");
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
function resolveRealtimeClientListeners(scope) {
|
|
@@ -57,7 +56,7 @@ function resolveRealtimeClientListeners(scope) {
|
|
|
57
56
|
return [];
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
return normalizeListenerEntries(scope.resolveTag(
|
|
59
|
+
return normalizeListenerEntries(scope.resolveTag("jskit.runtime.realtime.client.listeners"))
|
|
61
60
|
.map((entry) => normalizeRealtimeClientListener(entry))
|
|
62
61
|
.filter(Boolean);
|
|
63
62
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { KERNEL_TOKENS } from "@jskit-ai/kernel/shared/support/tokens";
|
|
2
1
|
import { normalizePositiveInteger, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
2
|
import { createProviderLogger as createSharedProviderLogger } from "@jskit-ai/kernel/shared/support/providerLogger";
|
|
4
3
|
import {
|
|
@@ -12,16 +11,11 @@ import {
|
|
|
12
11
|
configureSocketIoRedisAdapter,
|
|
13
12
|
closeSocketIoRedisConnections
|
|
14
13
|
} from "./runtime.js";
|
|
15
|
-
import {
|
|
16
|
-
REALTIME_RUNTIME_SERVER_TOKEN,
|
|
17
|
-
REALTIME_SOCKET_IO_SERVER_TOKEN
|
|
18
|
-
} from "./tokens.js";
|
|
19
14
|
|
|
20
15
|
const REALTIME_RUNTIME_SERVER_API = Object.freeze({
|
|
21
16
|
createSocketIoServer,
|
|
22
17
|
closeSocketIoServer
|
|
23
18
|
});
|
|
24
|
-
const REALTIME_DOMAIN_EVENT_BRIDGE_TOKEN = "runtime.realtime.domain-event-bridge";
|
|
25
19
|
|
|
26
20
|
const REALTIME_ROOM_ALL_CLIENTS = "clients";
|
|
27
21
|
const REALTIME_ROOM_ALL_USERS = "users";
|
|
@@ -85,7 +79,7 @@ function parseCookieHeader(value = "") {
|
|
|
85
79
|
|
|
86
80
|
function createProviderLogger(scope, { debugEnabled = false } = {}) {
|
|
87
81
|
const logger =
|
|
88
|
-
scope && typeof scope.has === "function" && scope.has(
|
|
82
|
+
scope && typeof scope.has === "function" && scope.has("jskit.logger") ? scope.make("jskit.logger") : null;
|
|
89
83
|
return createSharedProviderLogger(logger, { debugEnabled });
|
|
90
84
|
}
|
|
91
85
|
|
|
@@ -110,7 +104,7 @@ function parseDebugFlag(value, fallback = null) {
|
|
|
110
104
|
|
|
111
105
|
function resolveRealtimeServerDebugEnabled(scope) {
|
|
112
106
|
const appConfig = scope && typeof scope.has === "function" && scope.has("appConfig") ? scope.make("appConfig") : {};
|
|
113
|
-
const env = scope && typeof scope.has === "function" && scope.has(
|
|
107
|
+
const env = scope && typeof scope.has === "function" && scope.has("jskit.env") ? scope.make("jskit.env") : {};
|
|
114
108
|
const realtime = appConfig && typeof appConfig === "object" ? appConfig.realtime : null;
|
|
115
109
|
|
|
116
110
|
const envFlag = parseDebugFlag(env?.JSKIT_REALTIME_DEBUG);
|
|
@@ -383,12 +377,12 @@ async function resolveAudienceQueryRooms(userQuery, { scope, event, logger } = {
|
|
|
383
377
|
return [];
|
|
384
378
|
}
|
|
385
379
|
|
|
386
|
-
if (!scope || typeof scope.has !== "function" || typeof scope.make !== "function" || !scope.has(
|
|
380
|
+
if (!scope || typeof scope.has !== "function" || typeof scope.make !== "function" || !scope.has("jskit.database.knex")) {
|
|
387
381
|
logger.warn("Realtime audience userQuery requires runtime database token.");
|
|
388
382
|
return [];
|
|
389
383
|
}
|
|
390
384
|
|
|
391
|
-
const knex = scope.make(
|
|
385
|
+
const knex = scope.make("jskit.database.knex");
|
|
392
386
|
const queryResult = await userQuery({
|
|
393
387
|
knex,
|
|
394
388
|
event
|
|
@@ -493,7 +487,7 @@ function registerRealtimeSocketAudienceBootstrap(scope, io, logger) {
|
|
|
493
487
|
socket.join(REALTIME_ROOM_ALL_CLIENTS);
|
|
494
488
|
logger.debug(
|
|
495
489
|
{
|
|
496
|
-
listenerId:
|
|
490
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
497
491
|
stage: "socket.connection",
|
|
498
492
|
room: REALTIME_ROOM_ALL_CLIENTS
|
|
499
493
|
},
|
|
@@ -504,7 +498,7 @@ function registerRealtimeSocketAudienceBootstrap(scope, io, logger) {
|
|
|
504
498
|
if (actorId < 1) {
|
|
505
499
|
logger.debug(
|
|
506
500
|
{
|
|
507
|
-
listenerId:
|
|
501
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
508
502
|
stage: "socket.connection",
|
|
509
503
|
authenticated: false
|
|
510
504
|
},
|
|
@@ -520,7 +514,7 @@ function registerRealtimeSocketAudienceBootstrap(scope, io, logger) {
|
|
|
520
514
|
socket.join(roomForUser(actorId));
|
|
521
515
|
logger.debug(
|
|
522
516
|
{
|
|
523
|
-
listenerId:
|
|
517
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
524
518
|
stage: "socket.connection",
|
|
525
519
|
actorId,
|
|
526
520
|
joinedRooms: [REALTIME_ROOM_ALL_USERS, roomForUser(actorId)]
|
|
@@ -535,7 +529,7 @@ function registerRealtimeSocketAudienceBootstrap(scope, io, logger) {
|
|
|
535
529
|
}
|
|
536
530
|
logger.debug(
|
|
537
531
|
{
|
|
538
|
-
listenerId:
|
|
532
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
539
533
|
stage: "socket.connection",
|
|
540
534
|
actorId,
|
|
541
535
|
workspaceIds
|
|
@@ -545,7 +539,7 @@ function registerRealtimeSocketAudienceBootstrap(scope, io, logger) {
|
|
|
545
539
|
} catch (error) {
|
|
546
540
|
logger.warn(
|
|
547
541
|
{
|
|
548
|
-
listenerId:
|
|
542
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
549
543
|
error: String(error?.message || error || "unknown error")
|
|
550
544
|
},
|
|
551
545
|
"Realtime socket audience bootstrap failed."
|
|
@@ -555,30 +549,30 @@ function registerRealtimeSocketAudienceBootstrap(scope, io, logger) {
|
|
|
555
549
|
}
|
|
556
550
|
|
|
557
551
|
class RealtimeServiceProvider {
|
|
558
|
-
static id =
|
|
552
|
+
static id = "runtime.realtime";
|
|
559
553
|
|
|
560
554
|
register(app) {
|
|
561
555
|
if (!app || typeof app.singleton !== "function" || typeof app.tag !== "function") {
|
|
562
556
|
throw new Error("RealtimeServiceProvider requires application singleton()/tag().");
|
|
563
557
|
}
|
|
564
558
|
|
|
565
|
-
app.singleton(
|
|
566
|
-
app.singleton(
|
|
567
|
-
const fastify = scope.make(
|
|
559
|
+
app.singleton("runtime.realtime", () => REALTIME_RUNTIME_SERVER_API);
|
|
560
|
+
app.singleton("runtime.realtime.io", (scope) => {
|
|
561
|
+
const fastify = scope.make("jskit.fastify");
|
|
568
562
|
return createSocketIoServer({
|
|
569
563
|
fastify
|
|
570
564
|
});
|
|
571
565
|
});
|
|
572
566
|
|
|
573
|
-
registerDomainEventListener(app,
|
|
574
|
-
const io = scope.make(
|
|
567
|
+
registerDomainEventListener(app, "runtime.realtime.domain-event-bridge", (scope) => {
|
|
568
|
+
const io = scope.make("runtime.realtime.io");
|
|
575
569
|
const realtimeDispatchIndex = buildRealtimeDispatchIndex(resolveServiceRegistrations(scope));
|
|
576
570
|
const logger = createProviderLogger(scope, {
|
|
577
571
|
debugEnabled: resolveRealtimeServerDebugEnabled(scope)
|
|
578
572
|
});
|
|
579
573
|
|
|
580
574
|
return {
|
|
581
|
-
listenerId:
|
|
575
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
582
576
|
async handle(event = {}) {
|
|
583
577
|
const serviceToken = normalizeText(event?.meta?.service?.token);
|
|
584
578
|
const methodName = normalizeText(event?.meta?.service?.method);
|
|
@@ -586,7 +580,7 @@ class RealtimeServiceProvider {
|
|
|
586
580
|
if (!serviceToken || !methodName) {
|
|
587
581
|
logger.warn(
|
|
588
582
|
{
|
|
589
|
-
listenerId:
|
|
583
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
590
584
|
reason: "missing-service-meta",
|
|
591
585
|
meta: event?.meta || null
|
|
592
586
|
},
|
|
@@ -602,7 +596,7 @@ class RealtimeServiceProvider {
|
|
|
602
596
|
: dispatchersForMethod;
|
|
603
597
|
logger.debug(
|
|
604
598
|
{
|
|
605
|
-
listenerId:
|
|
599
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
606
600
|
serviceToken,
|
|
607
601
|
methodName,
|
|
608
602
|
emittedRealtimeEvent: emittedRealtimeEvent || null,
|
|
@@ -618,7 +612,7 @@ class RealtimeServiceProvider {
|
|
|
618
612
|
if (dispatchers.length < 1) {
|
|
619
613
|
logger.warn(
|
|
620
614
|
{
|
|
621
|
-
listenerId:
|
|
615
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
622
616
|
serviceToken,
|
|
623
617
|
methodName,
|
|
624
618
|
emittedRealtimeEvent: emittedRealtimeEvent || null
|
|
@@ -648,7 +642,7 @@ class RealtimeServiceProvider {
|
|
|
648
642
|
|
|
649
643
|
logger.debug(
|
|
650
644
|
{
|
|
651
|
-
listenerId:
|
|
645
|
+
listenerId: "runtime.realtime.domain-event-bridge",
|
|
652
646
|
socketEvent: dispatcher.event,
|
|
653
647
|
serviceToken,
|
|
654
648
|
methodName,
|
|
@@ -674,7 +668,7 @@ class RealtimeServiceProvider {
|
|
|
674
668
|
throw new Error("RealtimeServiceProvider requires application make().");
|
|
675
669
|
}
|
|
676
670
|
|
|
677
|
-
this.socketIoServer = app.make(
|
|
671
|
+
this.socketIoServer = app.make("runtime.realtime.io");
|
|
678
672
|
const debugEnabled = resolveRealtimeServerDebugEnabled(app);
|
|
679
673
|
const logger = createProviderLogger(app, {
|
|
680
674
|
debugEnabled
|
|
@@ -688,7 +682,7 @@ class RealtimeServiceProvider {
|
|
|
688
682
|
);
|
|
689
683
|
registerRealtimeSocketAudienceBootstrap(app, this.socketIoServer, logger);
|
|
690
684
|
|
|
691
|
-
const env = typeof app.has === "function" && app.has(
|
|
685
|
+
const env = typeof app.has === "function" && app.has("jskit.env") ? app.make("jskit.env") : {};
|
|
692
686
|
const redisUrl = resolveRealtimeRedisUrl(env);
|
|
693
687
|
this.redisConnection = await configureSocketIoRedisAdapter(this.socketIoServer, {
|
|
694
688
|
redisUrl
|
|
@@ -6,8 +6,6 @@ import * as serverRuntimeApi from "../src/server/runtime.js";
|
|
|
6
6
|
import * as clientApi from "../src/client/RealtimeClientProvider.js";
|
|
7
7
|
import * as clientRuntimeApi from "../src/client/runtime.js";
|
|
8
8
|
import * as clientListenerApi from "../src/client/listeners.js";
|
|
9
|
-
import * as serverTokens from "../src/server/tokens.js";
|
|
10
|
-
import * as clientTokens from "../src/client/tokens.js";
|
|
11
9
|
|
|
12
10
|
test("server entrypoint exports provider only", () => {
|
|
13
11
|
assert.equal(typeof serverApi.RealtimeServiceProvider, "function");
|
|
@@ -19,15 +17,6 @@ test("client entrypoint exports provider only", () => {
|
|
|
19
17
|
assert.deepEqual(Object.keys(clientApi).sort(), ["RealtimeClientProvider"]);
|
|
20
18
|
});
|
|
21
19
|
|
|
22
|
-
test("token entrypoints export runtime token constants", () => {
|
|
23
|
-
assert.equal(serverTokens.REALTIME_RUNTIME_SERVER_TOKEN, "runtime.realtime");
|
|
24
|
-
assert.equal(serverTokens.REALTIME_SOCKET_IO_SERVER_TOKEN, "runtime.realtime.io");
|
|
25
|
-
assert.equal(clientTokens.REALTIME_RUNTIME_CLIENT_TOKEN, "runtime.realtime.client");
|
|
26
|
-
assert.equal(clientTokens.REALTIME_SOCKET_CLIENT_TOKEN, "runtime.realtime.client.socket");
|
|
27
|
-
assert.equal(typeof clientTokens.REALTIME_SOCKET_CLIENT_INJECTION_KEY, "symbol");
|
|
28
|
-
assert.equal(typeof clientTokens.REALTIME_CLIENT_LISTENER_TAG, "symbol");
|
|
29
|
-
});
|
|
30
|
-
|
|
31
20
|
test("server runtime entrypoint exports server-only helpers", () => {
|
|
32
21
|
assert.equal(typeof serverRuntimeApi.createSocketIoServer, "function");
|
|
33
22
|
assert.equal(typeof serverRuntimeApi.closeSocketIoServer, "function");
|
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import test from "node:test";
|
|
3
3
|
import { createServer } from "node:http";
|
|
4
|
-
import { KERNEL_TOKENS } from "@jskit-ai/kernel/shared/support/tokens";
|
|
5
4
|
import { installServiceRegistrationApi } from "@jskit-ai/kernel/server/runtime";
|
|
6
5
|
|
|
7
6
|
import { RealtimeServiceProvider } from "../src/server/RealtimeServiceProvider.js";
|
|
8
7
|
import { RealtimeClientProvider } from "../src/client/RealtimeClientProvider.js";
|
|
9
8
|
import { registerRealtimeClientListener } from "../src/client/listeners.js";
|
|
10
|
-
import {
|
|
11
|
-
REALTIME_RUNTIME_SERVER_TOKEN,
|
|
12
|
-
REALTIME_SOCKET_IO_SERVER_TOKEN
|
|
13
|
-
} from "../src/server/tokens.js";
|
|
14
|
-
import {
|
|
15
|
-
REALTIME_RUNTIME_CLIENT_TOKEN,
|
|
16
|
-
REALTIME_SOCKET_CLIENT_TOKEN
|
|
17
|
-
} from "../src/client/tokens.js";
|
|
18
|
-
|
|
19
|
-
const DOMAIN_EVENT_LISTENER_TAG = Symbol.for("jskit.runtime.domainEvent.listeners");
|
|
20
9
|
|
|
21
10
|
function normalizeDomainEventListener(entry) {
|
|
22
11
|
if (typeof entry === "function") {
|
|
@@ -40,7 +29,8 @@ function createDomainEvents(scope) {
|
|
|
40
29
|
return Object.freeze({
|
|
41
30
|
async publish(event = {}) {
|
|
42
31
|
const payload = event && typeof event === "object" && !Array.isArray(event) ? event : {};
|
|
43
|
-
const listeners =
|
|
32
|
+
const listeners =
|
|
33
|
+
typeof scope?.resolveTag === "function" ? scope.resolveTag("jskit.runtime.domainEvent.listeners") : [];
|
|
44
34
|
for (const listenerEntry of listeners) {
|
|
45
35
|
const listener = normalizeDomainEventListener(listenerEntry);
|
|
46
36
|
if (!listener) {
|
|
@@ -104,23 +94,23 @@ function createSingletonApp() {
|
|
|
104
94
|
|
|
105
95
|
test("RealtimeServiceProvider registers runtime realtime server api", () => {
|
|
106
96
|
const app = createSingletonApp();
|
|
107
|
-
app.instance(
|
|
97
|
+
app.instance("jskit.fastify", {
|
|
108
98
|
server: createServer()
|
|
109
99
|
});
|
|
110
100
|
const provider = new RealtimeServiceProvider();
|
|
111
101
|
provider.register(app);
|
|
112
102
|
|
|
113
|
-
assert.equal(app.singletons.has(
|
|
114
|
-
assert.equal(app.singletons.has(
|
|
103
|
+
assert.equal(app.singletons.has("runtime.realtime"), true);
|
|
104
|
+
assert.equal(app.singletons.has("runtime.realtime.io"), true);
|
|
115
105
|
|
|
116
|
-
const api = app.make(
|
|
106
|
+
const api = app.make("runtime.realtime");
|
|
117
107
|
assert.equal(typeof api.createSocketIoServer, "function");
|
|
118
108
|
assert.equal(typeof api.closeSocketIoServer, "function");
|
|
119
109
|
});
|
|
120
110
|
|
|
121
111
|
test("RealtimeServiceProvider boot starts socket io and shutdown closes it", async () => {
|
|
122
112
|
const app = createSingletonApp();
|
|
123
|
-
app.instance(
|
|
113
|
+
app.instance("jskit.fastify", {
|
|
124
114
|
server: createServer()
|
|
125
115
|
});
|
|
126
116
|
|
|
@@ -128,7 +118,7 @@ test("RealtimeServiceProvider boot starts socket io and shutdown closes it", asy
|
|
|
128
118
|
provider.register(app);
|
|
129
119
|
provider.boot(app);
|
|
130
120
|
|
|
131
|
-
const io = app.make(
|
|
121
|
+
const io = app.make("runtime.realtime.io");
|
|
132
122
|
assert.equal(Boolean(io), true);
|
|
133
123
|
assert.equal(typeof io.on, "function");
|
|
134
124
|
|
|
@@ -140,10 +130,10 @@ test("RealtimeClientProvider registers runtime realtime client api", () => {
|
|
|
140
130
|
const provider = new RealtimeClientProvider();
|
|
141
131
|
provider.register(app);
|
|
142
132
|
|
|
143
|
-
assert.equal(app.singletons.has(
|
|
144
|
-
assert.equal(app.singletons.has(
|
|
133
|
+
assert.equal(app.singletons.has("runtime.realtime.client"), true);
|
|
134
|
+
assert.equal(app.singletons.has("runtime.realtime.client.socket"), true);
|
|
145
135
|
assert.equal(app.singletons.has("realtime.web.connection.indicator"), true);
|
|
146
|
-
const api = app.make(
|
|
136
|
+
const api = app.make("runtime.realtime.client");
|
|
147
137
|
assert.equal(typeof api.createSocketIoClient, "function");
|
|
148
138
|
assert.equal(typeof api.disconnectSocketIoClient, "function");
|
|
149
139
|
});
|
|
@@ -182,7 +172,7 @@ test("RealtimeClientProvider boots socket listeners and disconnects on shutdown"
|
|
|
182
172
|
};
|
|
183
173
|
|
|
184
174
|
let disconnectCalls = 0;
|
|
185
|
-
app.instance(
|
|
175
|
+
app.instance("runtime.realtime.client", {
|
|
186
176
|
createSocketIoClient() {
|
|
187
177
|
return socket;
|
|
188
178
|
},
|
|
@@ -223,7 +213,7 @@ test("RealtimeClientProvider boots socket listeners and disconnects on shutdown"
|
|
|
223
213
|
|
|
224
214
|
test("RealtimeServiceProvider bridges service event metadata to socket emissions", async () => {
|
|
225
215
|
const app = createSingletonApp();
|
|
226
|
-
app.instance(
|
|
216
|
+
app.instance("jskit.fastify", {
|
|
227
217
|
server: createServer()
|
|
228
218
|
});
|
|
229
219
|
app.singleton("authService", () => ({
|
|
@@ -268,7 +258,7 @@ test("RealtimeServiceProvider bridges service event metadata to socket emissions
|
|
|
268
258
|
provider.register(app);
|
|
269
259
|
await provider.boot(app);
|
|
270
260
|
|
|
271
|
-
const io = app.make(
|
|
261
|
+
const io = app.make("runtime.realtime.io");
|
|
272
262
|
const emitted = [];
|
|
273
263
|
io.to = (room) => {
|
|
274
264
|
return {
|
|
@@ -303,7 +293,7 @@ test("RealtimeServiceProvider bridges service event metadata to socket emissions
|
|
|
303
293
|
|
|
304
294
|
test("RealtimeServiceProvider resolves custom audience callback", async () => {
|
|
305
295
|
const app = createSingletonApp();
|
|
306
|
-
app.instance(
|
|
296
|
+
app.instance("jskit.fastify", {
|
|
307
297
|
server: createServer()
|
|
308
298
|
});
|
|
309
299
|
app.singleton("authService", () => ({
|
|
@@ -351,7 +341,7 @@ test("RealtimeServiceProvider resolves custom audience callback", async () => {
|
|
|
351
341
|
provider.register(app);
|
|
352
342
|
await provider.boot(app);
|
|
353
343
|
|
|
354
|
-
const io = app.make(
|
|
344
|
+
const io = app.make("runtime.realtime.io");
|
|
355
345
|
const emitted = [];
|
|
356
346
|
io.to = (room) => {
|
|
357
347
|
return {
|
|
@@ -389,7 +379,7 @@ test("RealtimeServiceProvider resolves custom audience callback", async () => {
|
|
|
389
379
|
|
|
390
380
|
test("RealtimeServiceProvider merges custom realtime payload with canonical domain event fields", async () => {
|
|
391
381
|
const app = createSingletonApp();
|
|
392
|
-
app.instance(
|
|
382
|
+
app.instance("jskit.fastify", {
|
|
393
383
|
server: createServer()
|
|
394
384
|
});
|
|
395
385
|
app.singleton("authService", () => ({
|
|
@@ -438,7 +428,7 @@ test("RealtimeServiceProvider merges custom realtime payload with canonical doma
|
|
|
438
428
|
provider.register(app);
|
|
439
429
|
await provider.boot(app);
|
|
440
430
|
|
|
441
|
-
const io = app.make(
|
|
431
|
+
const io = app.make("runtime.realtime.io");
|
|
442
432
|
const emitted = [];
|
|
443
433
|
io.to = (room) => {
|
|
444
434
|
return {
|
|
@@ -486,7 +476,7 @@ test("RealtimeServiceProvider merges custom realtime payload with canonical doma
|
|
|
486
476
|
|
|
487
477
|
test("RealtimeServiceProvider emits only the matching dispatcher event for each service method event", async () => {
|
|
488
478
|
const app = createSingletonApp();
|
|
489
|
-
app.instance(
|
|
479
|
+
app.instance("jskit.fastify", {
|
|
490
480
|
server: createServer()
|
|
491
481
|
});
|
|
492
482
|
app.singleton("authService", () => ({
|
|
@@ -542,7 +532,7 @@ test("RealtimeServiceProvider emits only the matching dispatcher event for each
|
|
|
542
532
|
provider.register(app);
|
|
543
533
|
await provider.boot(app);
|
|
544
534
|
|
|
545
|
-
const io = app.make(
|
|
535
|
+
const io = app.make("runtime.realtime.io");
|
|
546
536
|
const emitted = [];
|
|
547
537
|
io.to = (room) => {
|
|
548
538
|
return {
|
package/src/client/tokens.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const REALTIME_RUNTIME_CLIENT_TOKEN = "runtime.realtime.client";
|
|
2
|
-
const REALTIME_SOCKET_CLIENT_TOKEN = "runtime.realtime.client.socket";
|
|
3
|
-
const REALTIME_SOCKET_CLIENT_INJECTION_KEY = Symbol.for("jskit.realtime.runtime.client.socket");
|
|
4
|
-
const REALTIME_CLIENT_LISTENER_TAG = Symbol.for("jskit.runtime.realtime.client.listeners");
|
|
5
|
-
|
|
6
|
-
export {
|
|
7
|
-
REALTIME_RUNTIME_CLIENT_TOKEN,
|
|
8
|
-
REALTIME_SOCKET_CLIENT_TOKEN,
|
|
9
|
-
REALTIME_SOCKET_CLIENT_INJECTION_KEY,
|
|
10
|
-
REALTIME_CLIENT_LISTENER_TAG
|
|
11
|
-
};
|