@al8b/runtime-realtime 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +168 -0
- package/dist/createRealtimeBridge.d.mts +27 -0
- package/dist/createRealtimeBridge.d.ts +27 -0
- package/dist/createRealtimeBridge.js +68 -0
- package/dist/createRealtimeBridge.js.map +1 -0
- package/dist/createRealtimeBridge.mjs +45 -0
- package/dist/createRealtimeBridge.mjs.map +1 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +45 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types.d.mts +31 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +1 -0
- package/dist/types.mjs.map +1 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# @al8b/runtime-realtime
|
|
2
|
+
|
|
3
|
+
Realtime transport adapter for [@al8b/runtime](../runtime/README.md). Enables multiplayer and synchronization features through a pluggable realtime bridge.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @al8b/runtime-realtime @al8b/runtime
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Implement a `RealtimeBridge` for your chosen transport (WebSocket, WebRTC, etc.), then adapt it to the runtime:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { createRealtimeBridge, type RealtimeBridge } from "@al8b/runtime-realtime";
|
|
17
|
+
import { createRuntime } from "@al8b/runtime";
|
|
18
|
+
|
|
19
|
+
// Your realtime transport implementation
|
|
20
|
+
const myWebSocketBridge: RealtimeBridge = {
|
|
21
|
+
async connect() {
|
|
22
|
+
// Connect to websocket server
|
|
23
|
+
},
|
|
24
|
+
async disconnect() {
|
|
25
|
+
// Clean up websocket
|
|
26
|
+
},
|
|
27
|
+
send(channel, payload) {
|
|
28
|
+
// Send message on channel
|
|
29
|
+
},
|
|
30
|
+
subscribe(channel, handler) {
|
|
31
|
+
// Listen for messages on channel
|
|
32
|
+
return () => {
|
|
33
|
+
// Unsubscribe
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Adapt it to the runtime
|
|
39
|
+
const bridge = {
|
|
40
|
+
...createRealtimeBridge(myWebSocketBridge),
|
|
41
|
+
// Optionally add other bridge capabilities
|
|
42
|
+
getSession: () => getSessionFromServer(),
|
|
43
|
+
saveSnapshot: (snap) => cloudSave(snap),
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Create runtime with realtime bridge
|
|
47
|
+
const runtime = createRuntime({
|
|
48
|
+
sources: { /* ... */ },
|
|
49
|
+
resources: { /* ... */ },
|
|
50
|
+
bridge,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await runtime.start();
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## API
|
|
57
|
+
|
|
58
|
+
### `createRealtimeBridge(realtime: RealtimeBridge): RuntimeBridge`
|
|
59
|
+
|
|
60
|
+
Adapts a `RealtimeBridge` to a `RuntimeBridge`.
|
|
61
|
+
|
|
62
|
+
**Event Channels:**
|
|
63
|
+
|
|
64
|
+
The adapter subscribes to these channels:
|
|
65
|
+
- `"host.event"` - Incoming host events (mapped to HostEvent)
|
|
66
|
+
- `"player.message"` - Direct player-to-host messages
|
|
67
|
+
|
|
68
|
+
Game emissions are sent on:
|
|
69
|
+
- `"runtime.emit"` - Game-side events (name + payload)
|
|
70
|
+
|
|
71
|
+
**Composition:**
|
|
72
|
+
|
|
73
|
+
The returned `RuntimeBridge` only implements `emit` and `subscribe`. To add other capabilities:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
const bridge = {
|
|
77
|
+
...createRealtimeBridge(realtime),
|
|
78
|
+
request: async (name, payload) => { /* ... */ },
|
|
79
|
+
getSession: () => { /* ... */ },
|
|
80
|
+
saveSnapshot: async (snap) => { /* ... */ },
|
|
81
|
+
loadSnapshot: async (meta) => { /* ... */ },
|
|
82
|
+
};
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `RealtimeBridge`
|
|
86
|
+
|
|
87
|
+
Interface for a realtime transport:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
export interface RealtimeBridge {
|
|
91
|
+
connect(): Promise<void>;
|
|
92
|
+
disconnect(): Promise<void>;
|
|
93
|
+
send(channel: string, payload: unknown): void;
|
|
94
|
+
subscribe(channel: string, handler: (payload: unknown) => void): () => void;
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Example: WebSocket Transport
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { createRealtimeBridge } from "@al8b/runtime-realtime";
|
|
102
|
+
import type { RealtimeBridge } from "@al8b/runtime-realtime";
|
|
103
|
+
|
|
104
|
+
class WebSocketRealtimeBridge implements RealtimeBridge {
|
|
105
|
+
private ws: WebSocket | null = null;
|
|
106
|
+
private subscriptions = new Map<string, Set<(payload: unknown) => void>>();
|
|
107
|
+
|
|
108
|
+
async connect() {
|
|
109
|
+
return new Promise<void>((resolve, reject) => {
|
|
110
|
+
this.ws = new WebSocket("wss://realtime.example.com");
|
|
111
|
+
this.ws.onopen = () => resolve();
|
|
112
|
+
this.ws.onerror = () => reject(new Error("WebSocket connection failed"));
|
|
113
|
+
this.ws.onmessage = (event) => {
|
|
114
|
+
const message = JSON.parse(event.data);
|
|
115
|
+
const handlers = this.subscriptions.get(message.channel);
|
|
116
|
+
handlers?.forEach((h) => h(message.payload));
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async disconnect() {
|
|
122
|
+
this.ws?.close();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
send(channel: string, payload: unknown) {
|
|
126
|
+
this.ws?.send(JSON.stringify({ channel, payload }));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
subscribe(channel: string, handler: (payload: unknown) => void) {
|
|
130
|
+
if (!this.subscriptions.has(channel)) {
|
|
131
|
+
this.subscriptions.set(channel, new Set());
|
|
132
|
+
}
|
|
133
|
+
this.subscriptions.get(channel)!.add(handler);
|
|
134
|
+
return () => {
|
|
135
|
+
this.subscriptions.get(channel)?.delete(handler);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const bridge = createRealtimeBridge(new WebSocketRealtimeBridge());
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Multiplayer Patterns
|
|
144
|
+
|
|
145
|
+
Once integrated, games can emit realtime events:
|
|
146
|
+
|
|
147
|
+
```loot
|
|
148
|
+
// In LootiScript
|
|
149
|
+
host.emit("player.move", { x: 100, y: 50 })
|
|
150
|
+
host.emit("player.action", { action: "jump" })
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The realtime bridge forwards these to the backend, which can synchronize across players.
|
|
154
|
+
|
|
155
|
+
## Notes
|
|
156
|
+
|
|
157
|
+
- The adapter is transport-agnostic; implement `RealtimeBridge` for your chosen protocol
|
|
158
|
+
- Channel names are conventions between your game and backend; adjust as needed
|
|
159
|
+
- Reliability, ordering, and backpressure handling are transport responsibilities
|
|
160
|
+
- Games should not assume synchronous delivery; use async request/response patterns for critical data
|
|
161
|
+
|
|
162
|
+
## Scripts
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
bun run build # Build the package
|
|
166
|
+
bun run test # Run tests
|
|
167
|
+
bun run clean # Clean build artifacts
|
|
168
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { RealtimeBridge } from './types.mjs';
|
|
2
|
+
import { RuntimeBridge } from '@al8b/runtime';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create a RuntimeBridge adapter from a RealtimeBridge.
|
|
6
|
+
*
|
|
7
|
+
* This adapter maps realtime transport channels to RuntimeBridge events.
|
|
8
|
+
* Incoming messages on the `"host.event"` channel are delivered as HostEvent.
|
|
9
|
+
* Outgoing `bridge.emit` calls are sent on the `"runtime.emit"` channel.
|
|
10
|
+
*
|
|
11
|
+
* Note: This adapter does not implement `request`, `getSession`, `saveSnapshot`,
|
|
12
|
+
* or `loadSnapshot`. Compose those capabilities separately:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* const bridge = {
|
|
16
|
+
* ...createRealtimeBridge(realtime),
|
|
17
|
+
* getSession: () => fetchSession(userId),
|
|
18
|
+
* saveSnapshot: (snap) => cloudSave(userId, snap),
|
|
19
|
+
* };
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @param realtime - The realtime transport bridge
|
|
23
|
+
* @returns A RuntimeBridge that integrates with the realtime transport
|
|
24
|
+
*/
|
|
25
|
+
declare function createRealtimeBridge(realtime: RealtimeBridge): RuntimeBridge;
|
|
26
|
+
|
|
27
|
+
export { createRealtimeBridge };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { RealtimeBridge } from './types.js';
|
|
2
|
+
import { RuntimeBridge } from '@al8b/runtime';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create a RuntimeBridge adapter from a RealtimeBridge.
|
|
6
|
+
*
|
|
7
|
+
* This adapter maps realtime transport channels to RuntimeBridge events.
|
|
8
|
+
* Incoming messages on the `"host.event"` channel are delivered as HostEvent.
|
|
9
|
+
* Outgoing `bridge.emit` calls are sent on the `"runtime.emit"` channel.
|
|
10
|
+
*
|
|
11
|
+
* Note: This adapter does not implement `request`, `getSession`, `saveSnapshot`,
|
|
12
|
+
* or `loadSnapshot`. Compose those capabilities separately:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* const bridge = {
|
|
16
|
+
* ...createRealtimeBridge(realtime),
|
|
17
|
+
* getSession: () => fetchSession(userId),
|
|
18
|
+
* saveSnapshot: (snap) => cloudSave(userId, snap),
|
|
19
|
+
* };
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @param realtime - The realtime transport bridge
|
|
23
|
+
* @returns A RuntimeBridge that integrates with the realtime transport
|
|
24
|
+
*/
|
|
25
|
+
declare function createRealtimeBridge(realtime: RealtimeBridge): RuntimeBridge;
|
|
26
|
+
|
|
27
|
+
export { createRealtimeBridge };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/createRealtimeBridge.ts
|
|
22
|
+
var createRealtimeBridge_exports = {};
|
|
23
|
+
__export(createRealtimeBridge_exports, {
|
|
24
|
+
createRealtimeBridge: () => createRealtimeBridge
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(createRealtimeBridge_exports);
|
|
27
|
+
function createRealtimeBridge(realtime) {
|
|
28
|
+
const isHostEvent = /* @__PURE__ */ __name((payload) => {
|
|
29
|
+
return payload !== null && typeof payload === "object" && "type" in payload && typeof payload.type === "string";
|
|
30
|
+
}, "isHostEvent");
|
|
31
|
+
const subscribe = /* @__PURE__ */ __name((handler) => {
|
|
32
|
+
const unsub1 = realtime.subscribe("host.event", (payload) => {
|
|
33
|
+
if (isHostEvent(payload)) {
|
|
34
|
+
handler({
|
|
35
|
+
...payload,
|
|
36
|
+
source: payload.source ?? "realtime"
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const unsub2 = realtime.subscribe("player.message", (payload) => {
|
|
41
|
+
handler({
|
|
42
|
+
type: "player.message",
|
|
43
|
+
payload,
|
|
44
|
+
source: "realtime"
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
return () => {
|
|
48
|
+
unsub1();
|
|
49
|
+
unsub2();
|
|
50
|
+
};
|
|
51
|
+
}, "subscribe");
|
|
52
|
+
const emit = /* @__PURE__ */ __name((name, payload) => {
|
|
53
|
+
realtime.send("runtime.emit", {
|
|
54
|
+
name,
|
|
55
|
+
payload
|
|
56
|
+
});
|
|
57
|
+
}, "emit");
|
|
58
|
+
return {
|
|
59
|
+
emit,
|
|
60
|
+
subscribe
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
__name(createRealtimeBridge, "createRealtimeBridge");
|
|
64
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
65
|
+
0 && (module.exports = {
|
|
66
|
+
createRealtimeBridge
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=createRealtimeBridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/createRealtimeBridge.ts"],"sourcesContent":["import type { RuntimeBridge, HostEvent } from \"@al8b/runtime\";\nimport type { RealtimeBridge } from \"./types\";\n\n/**\n * Create a RuntimeBridge adapter from a RealtimeBridge.\n *\n * This adapter maps realtime transport channels to RuntimeBridge events.\n * Incoming messages on the `\"host.event\"` channel are delivered as HostEvent.\n * Outgoing `bridge.emit` calls are sent on the `\"runtime.emit\"` channel.\n *\n * Note: This adapter does not implement `request`, `getSession`, `saveSnapshot`,\n * or `loadSnapshot`. Compose those capabilities separately:\n *\n * ```ts\n * const bridge = {\n * ...createRealtimeBridge(realtime),\n * getSession: () => fetchSession(userId),\n * saveSnapshot: (snap) => cloudSave(userId, snap),\n * };\n * ```\n *\n * @param realtime - The realtime transport bridge\n * @returns A RuntimeBridge that integrates with the realtime transport\n */\nexport function createRealtimeBridge(realtime: RealtimeBridge): RuntimeBridge {\n\tconst isHostEvent = (payload: unknown): payload is HostEvent => {\n\t\treturn (\n\t\t\tpayload !== null &&\n\t\t\ttypeof payload === \"object\" &&\n\t\t\t\"type\" in payload &&\n\t\t\ttypeof (payload as any).type === \"string\"\n\t\t);\n\t};\n\n\tconst subscribe: RuntimeBridge[\"subscribe\"] = (handler) => {\n\t\t// Subscribe to incoming host events from realtime\n\t\tconst unsub1 = realtime.subscribe(\"host.event\", (payload) => {\n\t\t\tif (isHostEvent(payload)) {\n\t\t\t\thandler({\n\t\t\t\t\t...payload,\n\t\t\t\t\tsource: (payload.source ?? \"realtime\") as \"host\" | \"backend\" | \"realtime\",\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Also subscribe to player messages for direct game-to-host communication\n\t\tconst unsub2 = realtime.subscribe(\"player.message\", (payload) => {\n\t\t\thandler({\n\t\t\t\ttype: \"player.message\",\n\t\t\t\tpayload,\n\t\t\t\tsource: \"realtime\",\n\t\t\t});\n\t\t});\n\n\t\treturn () => {\n\t\t\tunsub1();\n\t\t\tunsub2();\n\t\t};\n\t};\n\n\tconst emit: RuntimeBridge[\"emit\"] = (name, payload) => {\n\t\t// Forward game emissions back to the realtime transport\n\t\trealtime.send(\"runtime.emit\", { name, payload });\n\t};\n\n\treturn {\n\t\temit,\n\t\tsubscribe,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAGA;;;;;AAqBO,SAASA,qBAAqBC,UAAwB;AAC5D,QAAMC,cAAc,wBAACC,YAAAA;AACpB,WACCA,YAAY,QACZ,OAAOA,YAAY,YACnB,UAAUA,WACV,OAAQA,QAAgBC,SAAS;EAEnC,GAPoB;AASpB,QAAMC,YAAwC,wBAACC,YAAAA;AAE9C,UAAMC,SAASN,SAASI,UAAU,cAAc,CAACF,YAAAA;AAChD,UAAID,YAAYC,OAAAA,GAAU;AACzBG,gBAAQ;UACP,GAAGH;UACHK,QAASL,QAAQK,UAAU;QAC5B,CAAA;MACD;IACD,CAAA;AAGA,UAAMC,SAASR,SAASI,UAAU,kBAAkB,CAACF,YAAAA;AACpDG,cAAQ;QACPF,MAAM;QACND;QACAK,QAAQ;MACT,CAAA;IACD,CAAA;AAEA,WAAO,MAAA;AACND,aAAAA;AACAE,aAAAA;IACD;EACD,GAxB8C;AA0B9C,QAAMC,OAA8B,wBAACC,MAAMR,YAAAA;AAE1CF,aAASW,KAAK,gBAAgB;MAAED;MAAMR;IAAQ,CAAA;EAC/C,GAHoC;AAKpC,SAAO;IACNO;IACAL;EACD;AACD;AA7CgBL;","names":["createRealtimeBridge","realtime","isHostEvent","payload","type","subscribe","handler","unsub1","source","unsub2","emit","name","send"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/createRealtimeBridge.ts
|
|
5
|
+
function createRealtimeBridge(realtime) {
|
|
6
|
+
const isHostEvent = /* @__PURE__ */ __name((payload) => {
|
|
7
|
+
return payload !== null && typeof payload === "object" && "type" in payload && typeof payload.type === "string";
|
|
8
|
+
}, "isHostEvent");
|
|
9
|
+
const subscribe = /* @__PURE__ */ __name((handler) => {
|
|
10
|
+
const unsub1 = realtime.subscribe("host.event", (payload) => {
|
|
11
|
+
if (isHostEvent(payload)) {
|
|
12
|
+
handler({
|
|
13
|
+
...payload,
|
|
14
|
+
source: payload.source ?? "realtime"
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const unsub2 = realtime.subscribe("player.message", (payload) => {
|
|
19
|
+
handler({
|
|
20
|
+
type: "player.message",
|
|
21
|
+
payload,
|
|
22
|
+
source: "realtime"
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
return () => {
|
|
26
|
+
unsub1();
|
|
27
|
+
unsub2();
|
|
28
|
+
};
|
|
29
|
+
}, "subscribe");
|
|
30
|
+
const emit = /* @__PURE__ */ __name((name, payload) => {
|
|
31
|
+
realtime.send("runtime.emit", {
|
|
32
|
+
name,
|
|
33
|
+
payload
|
|
34
|
+
});
|
|
35
|
+
}, "emit");
|
|
36
|
+
return {
|
|
37
|
+
emit,
|
|
38
|
+
subscribe
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
__name(createRealtimeBridge, "createRealtimeBridge");
|
|
42
|
+
export {
|
|
43
|
+
createRealtimeBridge
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=createRealtimeBridge.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/createRealtimeBridge.ts"],"sourcesContent":["import type { RuntimeBridge, HostEvent } from \"@al8b/runtime\";\nimport type { RealtimeBridge } from \"./types\";\n\n/**\n * Create a RuntimeBridge adapter from a RealtimeBridge.\n *\n * This adapter maps realtime transport channels to RuntimeBridge events.\n * Incoming messages on the `\"host.event\"` channel are delivered as HostEvent.\n * Outgoing `bridge.emit` calls are sent on the `\"runtime.emit\"` channel.\n *\n * Note: This adapter does not implement `request`, `getSession`, `saveSnapshot`,\n * or `loadSnapshot`. Compose those capabilities separately:\n *\n * ```ts\n * const bridge = {\n * ...createRealtimeBridge(realtime),\n * getSession: () => fetchSession(userId),\n * saveSnapshot: (snap) => cloudSave(userId, snap),\n * };\n * ```\n *\n * @param realtime - The realtime transport bridge\n * @returns A RuntimeBridge that integrates with the realtime transport\n */\nexport function createRealtimeBridge(realtime: RealtimeBridge): RuntimeBridge {\n\tconst isHostEvent = (payload: unknown): payload is HostEvent => {\n\t\treturn (\n\t\t\tpayload !== null &&\n\t\t\ttypeof payload === \"object\" &&\n\t\t\t\"type\" in payload &&\n\t\t\ttypeof (payload as any).type === \"string\"\n\t\t);\n\t};\n\n\tconst subscribe: RuntimeBridge[\"subscribe\"] = (handler) => {\n\t\t// Subscribe to incoming host events from realtime\n\t\tconst unsub1 = realtime.subscribe(\"host.event\", (payload) => {\n\t\t\tif (isHostEvent(payload)) {\n\t\t\t\thandler({\n\t\t\t\t\t...payload,\n\t\t\t\t\tsource: (payload.source ?? \"realtime\") as \"host\" | \"backend\" | \"realtime\",\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Also subscribe to player messages for direct game-to-host communication\n\t\tconst unsub2 = realtime.subscribe(\"player.message\", (payload) => {\n\t\t\thandler({\n\t\t\t\ttype: \"player.message\",\n\t\t\t\tpayload,\n\t\t\t\tsource: \"realtime\",\n\t\t\t});\n\t\t});\n\n\t\treturn () => {\n\t\t\tunsub1();\n\t\t\tunsub2();\n\t\t};\n\t};\n\n\tconst emit: RuntimeBridge[\"emit\"] = (name, payload) => {\n\t\t// Forward game emissions back to the realtime transport\n\t\trealtime.send(\"runtime.emit\", { name, payload });\n\t};\n\n\treturn {\n\t\temit,\n\t\tsubscribe,\n\t};\n}\n"],"mappings":";;;;AAwBO,SAASA,qBAAqBC,UAAwB;AAC5D,QAAMC,cAAc,wBAACC,YAAAA;AACpB,WACCA,YAAY,QACZ,OAAOA,YAAY,YACnB,UAAUA,WACV,OAAQA,QAAgBC,SAAS;EAEnC,GAPoB;AASpB,QAAMC,YAAwC,wBAACC,YAAAA;AAE9C,UAAMC,SAASN,SAASI,UAAU,cAAc,CAACF,YAAAA;AAChD,UAAID,YAAYC,OAAAA,GAAU;AACzBG,gBAAQ;UACP,GAAGH;UACHK,QAASL,QAAQK,UAAU;QAC5B,CAAA;MACD;IACD,CAAA;AAGA,UAAMC,SAASR,SAASI,UAAU,kBAAkB,CAACF,YAAAA;AACpDG,cAAQ;QACPF,MAAM;QACND;QACAK,QAAQ;MACT,CAAA;IACD,CAAA;AAEA,WAAO,MAAA;AACND,aAAAA;AACAE,aAAAA;IACD;EACD,GAxB8C;AA0B9C,QAAMC,OAA8B,wBAACC,MAAMR,YAAAA;AAE1CF,aAASW,KAAK,gBAAgB;MAAED;MAAMR;IAAQ,CAAA;EAC/C,GAHoC;AAKpC,SAAO;IACNO;IACAL;EACD;AACD;AA7CgBL;","names":["createRealtimeBridge","realtime","isHostEvent","payload","type","subscribe","handler","unsub1","source","unsub2","emit","name","send"]}
|
package/dist/index.d.mts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
createRealtimeBridge: () => createRealtimeBridge
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/createRealtimeBridge.ts
|
|
29
|
+
function createRealtimeBridge(realtime) {
|
|
30
|
+
const isHostEvent = /* @__PURE__ */ __name((payload) => {
|
|
31
|
+
return payload !== null && typeof payload === "object" && "type" in payload && typeof payload.type === "string";
|
|
32
|
+
}, "isHostEvent");
|
|
33
|
+
const subscribe = /* @__PURE__ */ __name((handler) => {
|
|
34
|
+
const unsub1 = realtime.subscribe("host.event", (payload) => {
|
|
35
|
+
if (isHostEvent(payload)) {
|
|
36
|
+
handler({
|
|
37
|
+
...payload,
|
|
38
|
+
source: payload.source ?? "realtime"
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
const unsub2 = realtime.subscribe("player.message", (payload) => {
|
|
43
|
+
handler({
|
|
44
|
+
type: "player.message",
|
|
45
|
+
payload,
|
|
46
|
+
source: "realtime"
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
return () => {
|
|
50
|
+
unsub1();
|
|
51
|
+
unsub2();
|
|
52
|
+
};
|
|
53
|
+
}, "subscribe");
|
|
54
|
+
const emit = /* @__PURE__ */ __name((name, payload) => {
|
|
55
|
+
realtime.send("runtime.emit", {
|
|
56
|
+
name,
|
|
57
|
+
payload
|
|
58
|
+
});
|
|
59
|
+
}, "emit");
|
|
60
|
+
return {
|
|
61
|
+
emit,
|
|
62
|
+
subscribe
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
__name(createRealtimeBridge, "createRealtimeBridge");
|
|
66
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
67
|
+
0 && (module.exports = {
|
|
68
|
+
createRealtimeBridge
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/createRealtimeBridge.ts"],"sourcesContent":["export type { RealtimeBridge } from \"./types\";\nexport { createRealtimeBridge } from \"./createRealtimeBridge\";\n","import type { RuntimeBridge, HostEvent } from \"@al8b/runtime\";\nimport type { RealtimeBridge } from \"./types\";\n\n/**\n * Create a RuntimeBridge adapter from a RealtimeBridge.\n *\n * This adapter maps realtime transport channels to RuntimeBridge events.\n * Incoming messages on the `\"host.event\"` channel are delivered as HostEvent.\n * Outgoing `bridge.emit` calls are sent on the `\"runtime.emit\"` channel.\n *\n * Note: This adapter does not implement `request`, `getSession`, `saveSnapshot`,\n * or `loadSnapshot`. Compose those capabilities separately:\n *\n * ```ts\n * const bridge = {\n * ...createRealtimeBridge(realtime),\n * getSession: () => fetchSession(userId),\n * saveSnapshot: (snap) => cloudSave(userId, snap),\n * };\n * ```\n *\n * @param realtime - The realtime transport bridge\n * @returns A RuntimeBridge that integrates with the realtime transport\n */\nexport function createRealtimeBridge(realtime: RealtimeBridge): RuntimeBridge {\n\tconst isHostEvent = (payload: unknown): payload is HostEvent => {\n\t\treturn (\n\t\t\tpayload !== null &&\n\t\t\ttypeof payload === \"object\" &&\n\t\t\t\"type\" in payload &&\n\t\t\ttypeof (payload as any).type === \"string\"\n\t\t);\n\t};\n\n\tconst subscribe: RuntimeBridge[\"subscribe\"] = (handler) => {\n\t\t// Subscribe to incoming host events from realtime\n\t\tconst unsub1 = realtime.subscribe(\"host.event\", (payload) => {\n\t\t\tif (isHostEvent(payload)) {\n\t\t\t\thandler({\n\t\t\t\t\t...payload,\n\t\t\t\t\tsource: (payload.source ?? \"realtime\") as \"host\" | \"backend\" | \"realtime\",\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Also subscribe to player messages for direct game-to-host communication\n\t\tconst unsub2 = realtime.subscribe(\"player.message\", (payload) => {\n\t\t\thandler({\n\t\t\t\ttype: \"player.message\",\n\t\t\t\tpayload,\n\t\t\t\tsource: \"realtime\",\n\t\t\t});\n\t\t});\n\n\t\treturn () => {\n\t\t\tunsub1();\n\t\t\tunsub2();\n\t\t};\n\t};\n\n\tconst emit: RuntimeBridge[\"emit\"] = (name, payload) => {\n\t\t// Forward game emissions back to the realtime transport\n\t\trealtime.send(\"runtime.emit\", { name, payload });\n\t};\n\n\treturn {\n\t\temit,\n\t\tsubscribe,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AACA;;;;;;;ACuBO,SAASA,qBAAqBC,UAAwB;AAC5D,QAAMC,cAAc,wBAACC,YAAAA;AACpB,WACCA,YAAY,QACZ,OAAOA,YAAY,YACnB,UAAUA,WACV,OAAQA,QAAgBC,SAAS;EAEnC,GAPoB;AASpB,QAAMC,YAAwC,wBAACC,YAAAA;AAE9C,UAAMC,SAASN,SAASI,UAAU,cAAc,CAACF,YAAAA;AAChD,UAAID,YAAYC,OAAAA,GAAU;AACzBG,gBAAQ;UACP,GAAGH;UACHK,QAASL,QAAQK,UAAU;QAC5B,CAAA;MACD;IACD,CAAA;AAGA,UAAMC,SAASR,SAASI,UAAU,kBAAkB,CAACF,YAAAA;AACpDG,cAAQ;QACPF,MAAM;QACND;QACAK,QAAQ;MACT,CAAA;IACD,CAAA;AAEA,WAAO,MAAA;AACND,aAAAA;AACAE,aAAAA;IACD;EACD,GAxB8C;AA0B9C,QAAMC,OAA8B,wBAACC,MAAMR,YAAAA;AAE1CF,aAASW,KAAK,gBAAgB;MAAED;MAAMR;IAAQ,CAAA;EAC/C,GAHoC;AAKpC,SAAO;IACNO;IACAL;EACD;AACD;AA7CgBL;","names":["createRealtimeBridge","realtime","isHostEvent","payload","type","subscribe","handler","unsub1","source","unsub2","emit","name","send"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/createRealtimeBridge.ts
|
|
5
|
+
function createRealtimeBridge(realtime) {
|
|
6
|
+
const isHostEvent = /* @__PURE__ */ __name((payload) => {
|
|
7
|
+
return payload !== null && typeof payload === "object" && "type" in payload && typeof payload.type === "string";
|
|
8
|
+
}, "isHostEvent");
|
|
9
|
+
const subscribe = /* @__PURE__ */ __name((handler) => {
|
|
10
|
+
const unsub1 = realtime.subscribe("host.event", (payload) => {
|
|
11
|
+
if (isHostEvent(payload)) {
|
|
12
|
+
handler({
|
|
13
|
+
...payload,
|
|
14
|
+
source: payload.source ?? "realtime"
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const unsub2 = realtime.subscribe("player.message", (payload) => {
|
|
19
|
+
handler({
|
|
20
|
+
type: "player.message",
|
|
21
|
+
payload,
|
|
22
|
+
source: "realtime"
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
return () => {
|
|
26
|
+
unsub1();
|
|
27
|
+
unsub2();
|
|
28
|
+
};
|
|
29
|
+
}, "subscribe");
|
|
30
|
+
const emit = /* @__PURE__ */ __name((name, payload) => {
|
|
31
|
+
realtime.send("runtime.emit", {
|
|
32
|
+
name,
|
|
33
|
+
payload
|
|
34
|
+
});
|
|
35
|
+
}, "emit");
|
|
36
|
+
return {
|
|
37
|
+
emit,
|
|
38
|
+
subscribe
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
__name(createRealtimeBridge, "createRealtimeBridge");
|
|
42
|
+
export {
|
|
43
|
+
createRealtimeBridge
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/createRealtimeBridge.ts"],"sourcesContent":["import type { RuntimeBridge, HostEvent } from \"@al8b/runtime\";\nimport type { RealtimeBridge } from \"./types\";\n\n/**\n * Create a RuntimeBridge adapter from a RealtimeBridge.\n *\n * This adapter maps realtime transport channels to RuntimeBridge events.\n * Incoming messages on the `\"host.event\"` channel are delivered as HostEvent.\n * Outgoing `bridge.emit` calls are sent on the `\"runtime.emit\"` channel.\n *\n * Note: This adapter does not implement `request`, `getSession`, `saveSnapshot`,\n * or `loadSnapshot`. Compose those capabilities separately:\n *\n * ```ts\n * const bridge = {\n * ...createRealtimeBridge(realtime),\n * getSession: () => fetchSession(userId),\n * saveSnapshot: (snap) => cloudSave(userId, snap),\n * };\n * ```\n *\n * @param realtime - The realtime transport bridge\n * @returns A RuntimeBridge that integrates with the realtime transport\n */\nexport function createRealtimeBridge(realtime: RealtimeBridge): RuntimeBridge {\n\tconst isHostEvent = (payload: unknown): payload is HostEvent => {\n\t\treturn (\n\t\t\tpayload !== null &&\n\t\t\ttypeof payload === \"object\" &&\n\t\t\t\"type\" in payload &&\n\t\t\ttypeof (payload as any).type === \"string\"\n\t\t);\n\t};\n\n\tconst subscribe: RuntimeBridge[\"subscribe\"] = (handler) => {\n\t\t// Subscribe to incoming host events from realtime\n\t\tconst unsub1 = realtime.subscribe(\"host.event\", (payload) => {\n\t\t\tif (isHostEvent(payload)) {\n\t\t\t\thandler({\n\t\t\t\t\t...payload,\n\t\t\t\t\tsource: (payload.source ?? \"realtime\") as \"host\" | \"backend\" | \"realtime\",\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Also subscribe to player messages for direct game-to-host communication\n\t\tconst unsub2 = realtime.subscribe(\"player.message\", (payload) => {\n\t\t\thandler({\n\t\t\t\ttype: \"player.message\",\n\t\t\t\tpayload,\n\t\t\t\tsource: \"realtime\",\n\t\t\t});\n\t\t});\n\n\t\treturn () => {\n\t\t\tunsub1();\n\t\t\tunsub2();\n\t\t};\n\t};\n\n\tconst emit: RuntimeBridge[\"emit\"] = (name, payload) => {\n\t\t// Forward game emissions back to the realtime transport\n\t\trealtime.send(\"runtime.emit\", { name, payload });\n\t};\n\n\treturn {\n\t\temit,\n\t\tsubscribe,\n\t};\n}\n"],"mappings":";;;;AAwBO,SAASA,qBAAqBC,UAAwB;AAC5D,QAAMC,cAAc,wBAACC,YAAAA;AACpB,WACCA,YAAY,QACZ,OAAOA,YAAY,YACnB,UAAUA,WACV,OAAQA,QAAgBC,SAAS;EAEnC,GAPoB;AASpB,QAAMC,YAAwC,wBAACC,YAAAA;AAE9C,UAAMC,SAASN,SAASI,UAAU,cAAc,CAACF,YAAAA;AAChD,UAAID,YAAYC,OAAAA,GAAU;AACzBG,gBAAQ;UACP,GAAGH;UACHK,QAASL,QAAQK,UAAU;QAC5B,CAAA;MACD;IACD,CAAA;AAGA,UAAMC,SAASR,SAASI,UAAU,kBAAkB,CAACF,YAAAA;AACpDG,cAAQ;QACPF,MAAM;QACND;QACAK,QAAQ;MACT,CAAA;IACD,CAAA;AAEA,WAAO,MAAA;AACND,aAAAA;AACAE,aAAAA;IACD;EACD,GAxB8C;AA0B9C,QAAMC,OAA8B,wBAACC,MAAMR,YAAAA;AAE1CF,aAASW,KAAK,gBAAgB;MAAED;MAAMR;IAAQ,CAAA;EAC/C,GAHoC;AAKpC,SAAO;IACNO;IACAL;EACD;AACD;AA7CgBL;","names":["createRealtimeBridge","realtime","isHostEvent","payload","type","subscribe","handler","unsub1","source","unsub2","emit","name","send"]}
|
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Realtime transport bridge for multiplayer and synchronization features.
|
|
3
|
+
*
|
|
4
|
+
* This interface abstracts over specific realtime transports (WebSocket, WebRTC, etc.)
|
|
5
|
+
* and can be adapted into a RuntimeBridge for host-side communication.
|
|
6
|
+
*/
|
|
7
|
+
interface RealtimeBridge {
|
|
8
|
+
/**
|
|
9
|
+
* Connect to the realtime service.
|
|
10
|
+
*/
|
|
11
|
+
connect(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Disconnect from the realtime service.
|
|
14
|
+
*/
|
|
15
|
+
disconnect(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Send a message on a channel.
|
|
18
|
+
* @param channel - Channel name
|
|
19
|
+
* @param payload - Message payload
|
|
20
|
+
*/
|
|
21
|
+
send(channel: string, payload: unknown): void;
|
|
22
|
+
/**
|
|
23
|
+
* Subscribe to a channel.
|
|
24
|
+
* @param channel - Channel name
|
|
25
|
+
* @param handler - Called when a message arrives on the channel
|
|
26
|
+
* @returns Unsubscribe function
|
|
27
|
+
*/
|
|
28
|
+
subscribe(channel: string, handler: (payload: unknown) => void): () => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type { RealtimeBridge };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Realtime transport bridge for multiplayer and synchronization features.
|
|
3
|
+
*
|
|
4
|
+
* This interface abstracts over specific realtime transports (WebSocket, WebRTC, etc.)
|
|
5
|
+
* and can be adapted into a RuntimeBridge for host-side communication.
|
|
6
|
+
*/
|
|
7
|
+
interface RealtimeBridge {
|
|
8
|
+
/**
|
|
9
|
+
* Connect to the realtime service.
|
|
10
|
+
*/
|
|
11
|
+
connect(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Disconnect from the realtime service.
|
|
14
|
+
*/
|
|
15
|
+
disconnect(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Send a message on a channel.
|
|
18
|
+
* @param channel - Channel name
|
|
19
|
+
* @param payload - Message payload
|
|
20
|
+
*/
|
|
21
|
+
send(channel: string, payload: unknown): void;
|
|
22
|
+
/**
|
|
23
|
+
* Subscribe to a channel.
|
|
24
|
+
* @param channel - Channel name
|
|
25
|
+
* @param handler - Called when a message arrives on the channel
|
|
26
|
+
* @returns Unsubscribe function
|
|
27
|
+
*/
|
|
28
|
+
subscribe(channel: string, handler: (payload: unknown) => void): () => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type { RealtimeBridge };
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/types.ts
|
|
17
|
+
var types_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(types_exports);
|
|
19
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * Realtime transport bridge for multiplayer and synchronization features.\n *\n * This interface abstracts over specific realtime transports (WebSocket, WebRTC, etc.)\n * and can be adapted into a RuntimeBridge for host-side communication.\n */\nexport interface RealtimeBridge {\n\t/**\n\t * Connect to the realtime service.\n\t */\n\tconnect(): Promise<void>;\n\n\t/**\n\t * Disconnect from the realtime service.\n\t */\n\tdisconnect(): Promise<void>;\n\n\t/**\n\t * Send a message on a channel.\n\t * @param channel - Channel name\n\t * @param payload - Message payload\n\t */\n\tsend(channel: string, payload: unknown): void;\n\n\t/**\n\t * Subscribe to a channel.\n\t * @param channel - Channel name\n\t * @param handler - Called when a message arrives on the channel\n\t * @returns Unsubscribe function\n\t */\n\tsubscribe(channel: string, handler: (payload: unknown) => void): () => void;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;;","names":[]}
|
package/dist/types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@al8b/runtime-realtime",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"sideEffects": false,
|
|
5
|
+
"files": [
|
|
6
|
+
"dist/**/*",
|
|
7
|
+
"README.md",
|
|
8
|
+
"package.json"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup",
|
|
12
|
+
"clean": "bun --bun ../../../scripts/clean-package.mjs dist",
|
|
13
|
+
"test": "vitest run --passWithNoTests"
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"module": "./dist/index.mjs",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.mjs",
|
|
22
|
+
"require": "./dist/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./package.json": "./package.json"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@al8b/runtime": "workspace:*"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"typescript": "~5.9.3"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"runtime",
|
|
34
|
+
"realtime",
|
|
35
|
+
"multiplayer",
|
|
36
|
+
"websocket"
|
|
37
|
+
],
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
}
|
|
41
|
+
}
|