@holo-js/broadcast 0.1.3
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/auth.d.ts +35 -0
- package/dist/auth.mjs +18 -0
- package/dist/chunk-5XRABYQH.mjs +404 -0
- package/dist/chunk-742LGR5P.mjs +528 -0
- package/dist/chunk-QW6MHEWS.mjs +281 -0
- package/dist/contracts.d.ts +287 -0
- package/dist/contracts.mjs +32 -0
- package/dist/index.d.ts +177 -0
- package/dist/index.mjs +1445 -0
- package/dist/runtime.d.ts +91 -0
- package/dist/runtime.mjs +19 -0
- package/package.json +61 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
// src/contracts.ts
|
|
2
|
+
var HOLO_BROADCAST_DEFINITION_MARKER = /* @__PURE__ */ Symbol.for("holo-js.broadcast.definition");
|
|
3
|
+
var HOLO_CHANNEL_DEFINITION_MARKER = /* @__PURE__ */ Symbol.for("holo-js.broadcast.channel");
|
|
4
|
+
function isReadonlyArray(value) {
|
|
5
|
+
return Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function isPlainObject(value) {
|
|
8
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
9
|
+
}
|
|
10
|
+
function normalizeOptionalString(value, label) {
|
|
11
|
+
if (typeof value === "undefined") {
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
const normalized = value.trim();
|
|
15
|
+
if (!normalized) {
|
|
16
|
+
throw new Error(`[Holo Broadcast] ${label} must be a non-empty string when provided.`);
|
|
17
|
+
}
|
|
18
|
+
return normalized;
|
|
19
|
+
}
|
|
20
|
+
function normalizeDelayValue(value) {
|
|
21
|
+
if (typeof value === "undefined") {
|
|
22
|
+
return void 0;
|
|
23
|
+
}
|
|
24
|
+
if (typeof value === "number") {
|
|
25
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
26
|
+
throw new TypeError("[Holo Broadcast] Broadcast delay must be a finite number greater than or equal to 0.");
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
if (!(value instanceof Date) || Number.isNaN(value.getTime())) {
|
|
31
|
+
throw new TypeError("[Holo Broadcast] Broadcast delay dates must be valid Date instances.");
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function normalizeJsonValue(value, path) {
|
|
36
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(value)) {
|
|
40
|
+
return Object.freeze(value.map((entry, index) => normalizeJsonValue(entry, `${path}[${index}]`)));
|
|
41
|
+
}
|
|
42
|
+
if (isPlainObject(value)) {
|
|
43
|
+
return Object.freeze(Object.fromEntries(
|
|
44
|
+
Object.entries(value).map(([key, entry]) => {
|
|
45
|
+
if (!key.trim()) {
|
|
46
|
+
throw new Error(`[Holo Broadcast] ${path} must not include empty payload keys.`);
|
|
47
|
+
}
|
|
48
|
+
return [key, normalizeJsonValue(entry, `${path}.${key}`)];
|
|
49
|
+
})
|
|
50
|
+
));
|
|
51
|
+
}
|
|
52
|
+
throw new Error(`[Holo Broadcast] ${path} must be JSON-serializable.`);
|
|
53
|
+
}
|
|
54
|
+
function normalizePayload(payload) {
|
|
55
|
+
const resolved = typeof payload === "function" ? payload() : payload;
|
|
56
|
+
if (!isPlainObject(resolved)) {
|
|
57
|
+
throw new Error("[Holo Broadcast] Broadcast payload must be a plain object.");
|
|
58
|
+
}
|
|
59
|
+
return normalizeJsonValue(resolved, "Broadcast payload");
|
|
60
|
+
}
|
|
61
|
+
function normalizeQueueOptions(queue) {
|
|
62
|
+
if (typeof queue === "boolean" || typeof queue === "undefined") {
|
|
63
|
+
return Object.freeze({
|
|
64
|
+
queued: queue === true,
|
|
65
|
+
afterCommit: false
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const connection = normalizeOptionalString(queue.connection, "Broadcast queue connection");
|
|
69
|
+
const queueName = normalizeOptionalString(queue.queue, "Broadcast queue name");
|
|
70
|
+
const afterCommit = queue.afterCommit === true;
|
|
71
|
+
const queued = queue.queued === true;
|
|
72
|
+
if (!queued && (connection || queueName)) {
|
|
73
|
+
throw new Error("[Holo Broadcast] Broadcast queue metadata requires queued: true.");
|
|
74
|
+
}
|
|
75
|
+
return Object.freeze({
|
|
76
|
+
queued,
|
|
77
|
+
...typeof connection === "undefined" ? {} : { connection },
|
|
78
|
+
...typeof queueName === "undefined" ? {} : { queue: queueName },
|
|
79
|
+
afterCommit
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function normalizePatternSegment(segment, label) {
|
|
83
|
+
if (!segment) {
|
|
84
|
+
throw new Error(`[Holo Broadcast] ${label} must not contain empty path segments.`);
|
|
85
|
+
}
|
|
86
|
+
const wildcardMatch = segment.match(/^\{([A-Za-z_][A-Za-z0-9_]*)\}$/);
|
|
87
|
+
if (wildcardMatch) {
|
|
88
|
+
return wildcardMatch[1];
|
|
89
|
+
}
|
|
90
|
+
if (!/^[A-Za-z0-9_-]+$/.test(segment)) {
|
|
91
|
+
throw new Error(`[Holo Broadcast] ${label} contains invalid segment "${segment}".`);
|
|
92
|
+
}
|
|
93
|
+
return segment;
|
|
94
|
+
}
|
|
95
|
+
function extractChannelPatternParamNames(pattern) {
|
|
96
|
+
const normalized = normalizeChannelPattern(pattern, "Channel pattern");
|
|
97
|
+
const params = normalized.split(".").map((segment) => segment.match(/^\{([A-Za-z_][A-Za-z0-9_]*)\}$/)?.[1]).filter((value) => typeof value === "string");
|
|
98
|
+
const duplicates = params.filter((param, index) => params.indexOf(param) !== index);
|
|
99
|
+
if (duplicates.length > 0) {
|
|
100
|
+
throw new Error(`[Holo Broadcast] Channel pattern "${normalized}" contains duplicate params.`);
|
|
101
|
+
}
|
|
102
|
+
return Object.freeze(params);
|
|
103
|
+
}
|
|
104
|
+
function normalizeChannelPattern(pattern, label = "Channel pattern") {
|
|
105
|
+
const normalized = normalizeOptionalString(pattern, label) ?? (() => {
|
|
106
|
+
throw new Error(`[Holo Broadcast] ${label} must be a non-empty string.`);
|
|
107
|
+
})();
|
|
108
|
+
normalized.split(".").forEach((segment) => normalizePatternSegment(segment, label));
|
|
109
|
+
return normalized;
|
|
110
|
+
}
|
|
111
|
+
function normalizeTargetParams(pattern, params) {
|
|
112
|
+
const expectedParams = extractChannelPatternParamNames(pattern);
|
|
113
|
+
const providedEntries = Object.entries(params ?? {}).filter(([, value]) => typeof value !== "undefined").map(([key, value]) => {
|
|
114
|
+
const normalizedKey = key.trim();
|
|
115
|
+
if (!normalizedKey) {
|
|
116
|
+
throw new Error("[Holo Broadcast] Channel target params must not include empty keys.");
|
|
117
|
+
}
|
|
118
|
+
return [normalizedKey, String(value)];
|
|
119
|
+
});
|
|
120
|
+
const provided = Object.freeze(Object.fromEntries(providedEntries));
|
|
121
|
+
const providedNames = Object.keys(provided);
|
|
122
|
+
for (const param of expectedParams) {
|
|
123
|
+
if (!(param in provided)) {
|
|
124
|
+
throw new Error(`[Holo Broadcast] Channel target for "${pattern}" must define param "${param}".`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
for (const param of providedNames) {
|
|
128
|
+
if (!expectedParams.includes(param)) {
|
|
129
|
+
throw new Error(`[Holo Broadcast] Channel target for "${pattern}" does not define param "${param}".`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return provided;
|
|
133
|
+
}
|
|
134
|
+
function formatChannelPattern(pattern, params) {
|
|
135
|
+
return normalizeChannelPattern(pattern).replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_match, key) => {
|
|
136
|
+
const value = params[key];
|
|
137
|
+
if (typeof value !== "string") {
|
|
138
|
+
throw new Error(`[Holo Broadcast] Channel target for "${pattern}" is missing param "${key}".`);
|
|
139
|
+
}
|
|
140
|
+
return value;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
function createChannelTarget(type, pattern, params) {
|
|
144
|
+
const normalizedPattern = normalizeChannelPattern(pattern, "Channel target pattern");
|
|
145
|
+
return Object.freeze({
|
|
146
|
+
type,
|
|
147
|
+
pattern: normalizedPattern,
|
|
148
|
+
params: normalizeTargetParams(normalizedPattern, params)
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function normalizeChannels(input) {
|
|
152
|
+
const resolved = typeof input === "function" ? input() : input;
|
|
153
|
+
if (!isReadonlyArray(resolved) || resolved.length === 0) {
|
|
154
|
+
throw new Error("[Holo Broadcast] Broadcast definitions must target at least one channel.");
|
|
155
|
+
}
|
|
156
|
+
const normalizedChannels = resolved.map((channel2, index) => {
|
|
157
|
+
if (!isBroadcastChannelTarget(channel2)) {
|
|
158
|
+
throw new Error(`[Holo Broadcast] Broadcast channel at index ${index} must be created through channel helpers.`);
|
|
159
|
+
}
|
|
160
|
+
return Object.freeze({
|
|
161
|
+
type: channel2.type,
|
|
162
|
+
pattern: normalizeChannelPattern(channel2.pattern, `Broadcast channel ${index} pattern`),
|
|
163
|
+
params: normalizeTargetParams(channel2.pattern, channel2.params)
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
return Object.freeze(normalizedChannels);
|
|
167
|
+
}
|
|
168
|
+
function normalizeWhisperDefinitions(whispers) {
|
|
169
|
+
const entries = Object.entries(whispers ?? {});
|
|
170
|
+
const normalizedEntries = entries.map(([name, schema]) => {
|
|
171
|
+
const normalizedName = normalizeOptionalString(name, "Whisper event name");
|
|
172
|
+
if (!normalizedName) {
|
|
173
|
+
throw new Error("[Holo Broadcast] Whisper event names must be non-empty strings.");
|
|
174
|
+
}
|
|
175
|
+
if (!schema || typeof schema !== "object" || !("~standard" in schema)) {
|
|
176
|
+
throw new Error(`[Holo Broadcast] Whisper "${normalizedName}" must be a validation schema.`);
|
|
177
|
+
}
|
|
178
|
+
return [normalizedName, schema];
|
|
179
|
+
});
|
|
180
|
+
return Object.freeze(Object.fromEntries(normalizedEntries));
|
|
181
|
+
}
|
|
182
|
+
function isBroadcastChannelTarget(value) {
|
|
183
|
+
return isPlainObject(value) && typeof value.pattern === "string" && typeof value.type === "string" && isPlainObject(value.params);
|
|
184
|
+
}
|
|
185
|
+
function isBroadcastDefinition(value) {
|
|
186
|
+
return isPlainObject(value) && HOLO_BROADCAST_DEFINITION_MARKER in value;
|
|
187
|
+
}
|
|
188
|
+
function isChannelDefinition(value) {
|
|
189
|
+
return isPlainObject(value) && HOLO_CHANNEL_DEFINITION_MARKER in value;
|
|
190
|
+
}
|
|
191
|
+
function normalizeBroadcastDefinition(definition) {
|
|
192
|
+
if (!isPlainObject(definition)) {
|
|
193
|
+
throw new Error("[Holo Broadcast] Broadcast definitions must be plain objects.");
|
|
194
|
+
}
|
|
195
|
+
const normalizedInput = definition;
|
|
196
|
+
const name = normalizeOptionalString(normalizedInput.name, "Broadcast name");
|
|
197
|
+
const normalized = {
|
|
198
|
+
...typeof name === "undefined" ? {} : { name },
|
|
199
|
+
channels: normalizeChannels(normalizedInput.channels),
|
|
200
|
+
payload: normalizePayload(normalizedInput.payload),
|
|
201
|
+
queue: normalizeQueueOptions(normalizedInput.queue),
|
|
202
|
+
...typeof normalizedInput.delay === "undefined" ? {} : { delay: normalizeDelayValue(normalizedInput.delay) }
|
|
203
|
+
};
|
|
204
|
+
return normalized;
|
|
205
|
+
}
|
|
206
|
+
function defineBroadcast(definition) {
|
|
207
|
+
const normalized = { ...normalizeBroadcastDefinition(definition) };
|
|
208
|
+
Object.defineProperty(normalized, HOLO_BROADCAST_DEFINITION_MARKER, {
|
|
209
|
+
value: true,
|
|
210
|
+
enumerable: false
|
|
211
|
+
});
|
|
212
|
+
return Object.freeze(normalized);
|
|
213
|
+
}
|
|
214
|
+
function normalizeChannelDefinition(pattern, definition) {
|
|
215
|
+
if (!isPlainObject(definition) || typeof definition.authorize !== "function") {
|
|
216
|
+
throw new Error("[Holo Broadcast] Channel definitions must define an authorize(...) function.");
|
|
217
|
+
}
|
|
218
|
+
if (definition.type !== "private" && definition.type !== "presence") {
|
|
219
|
+
throw new Error('[Holo Broadcast] Channel definitions must use type "private" or "presence".');
|
|
220
|
+
}
|
|
221
|
+
return {
|
|
222
|
+
pattern: normalizeChannelPattern(pattern, "Channel pattern"),
|
|
223
|
+
type: definition.type,
|
|
224
|
+
authorize: definition.authorize,
|
|
225
|
+
whispers: normalizeWhisperDefinitions(definition.whispers)
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function defineChannel(pattern, definition) {
|
|
229
|
+
const normalized = { ...normalizeChannelDefinition(pattern, definition) };
|
|
230
|
+
Object.defineProperty(normalized, HOLO_CHANNEL_DEFINITION_MARKER, {
|
|
231
|
+
value: true,
|
|
232
|
+
enumerable: false
|
|
233
|
+
});
|
|
234
|
+
return Object.freeze(normalized);
|
|
235
|
+
}
|
|
236
|
+
function channel(pattern, params) {
|
|
237
|
+
return createChannelTarget("public", pattern, params);
|
|
238
|
+
}
|
|
239
|
+
function privateChannel(pattern, params) {
|
|
240
|
+
return createChannelTarget("private", pattern, params);
|
|
241
|
+
}
|
|
242
|
+
function presenceChannel(pattern, params) {
|
|
243
|
+
return createChannelTarget("presence", pattern, params);
|
|
244
|
+
}
|
|
245
|
+
var broadcastInternals = {
|
|
246
|
+
extractChannelPatternParamNames,
|
|
247
|
+
formatChannelPattern,
|
|
248
|
+
hasBroadcastDefinitionMarker(value) {
|
|
249
|
+
return isPlainObject(value) && HOLO_BROADCAST_DEFINITION_MARKER in value;
|
|
250
|
+
},
|
|
251
|
+
hasChannelDefinitionMarker(value) {
|
|
252
|
+
return isPlainObject(value) && HOLO_CHANNEL_DEFINITION_MARKER in value;
|
|
253
|
+
},
|
|
254
|
+
isBroadcastChannelTarget,
|
|
255
|
+
isPlainObject,
|
|
256
|
+
isReadonlyArray,
|
|
257
|
+
normalizeBroadcastDefinition,
|
|
258
|
+
normalizeChannelDefinition,
|
|
259
|
+
normalizeChannelPattern,
|
|
260
|
+
normalizeDelayValue,
|
|
261
|
+
normalizeJsonValue,
|
|
262
|
+
normalizeQueueOptions,
|
|
263
|
+
normalizeWhisperDefinitions
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
export {
|
|
267
|
+
extractChannelPatternParamNames,
|
|
268
|
+
normalizeChannelPattern,
|
|
269
|
+
formatChannelPattern,
|
|
270
|
+
isBroadcastChannelTarget,
|
|
271
|
+
isBroadcastDefinition,
|
|
272
|
+
isChannelDefinition,
|
|
273
|
+
normalizeBroadcastDefinition,
|
|
274
|
+
defineBroadcast,
|
|
275
|
+
normalizeChannelDefinition,
|
|
276
|
+
defineChannel,
|
|
277
|
+
channel,
|
|
278
|
+
privateChannel,
|
|
279
|
+
presenceChannel,
|
|
280
|
+
broadcastInternals
|
|
281
|
+
};
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { NormalizedHoloBroadcastConfig } from '@holo-js/config';
|
|
2
|
+
import { ValidationSchema, InferSchemaData } from '@holo-js/validation';
|
|
3
|
+
|
|
4
|
+
type BroadcastJsonPrimitive = string | number | boolean | null;
|
|
5
|
+
type BroadcastJsonValue = BroadcastJsonPrimitive | readonly BroadcastJsonValue[] | BroadcastJsonObject;
|
|
6
|
+
type BroadcastJsonObject = {
|
|
7
|
+
readonly [key: string]: BroadcastJsonValue;
|
|
8
|
+
};
|
|
9
|
+
type BroadcastChannelType = 'public' | 'private' | 'presence';
|
|
10
|
+
type BroadcastDelayValue = number | Date;
|
|
11
|
+
type ExtractChannelPatternParamNames<TPattern extends string> = TPattern extends `${string}{${infer TParam}}${infer TRest}` ? TParam | ExtractChannelPatternParamNames<TRest> : never;
|
|
12
|
+
type ChannelPatternParams<TPattern extends string> = [ExtractChannelPatternParamNames<TPattern>] extends [never] ? Record<string, never> : Readonly<Record<ExtractChannelPatternParamNames<TPattern>, string>>;
|
|
13
|
+
interface BroadcastTargetParamInput {
|
|
14
|
+
readonly [key: string]: string | number | boolean | null | undefined;
|
|
15
|
+
}
|
|
16
|
+
interface BroadcastChannelTarget<TType extends BroadcastChannelType = BroadcastChannelType, TPattern extends string = string, TParams extends Record<string, string> = Record<string, string>> {
|
|
17
|
+
readonly type: TType;
|
|
18
|
+
readonly pattern: TPattern;
|
|
19
|
+
readonly params: Readonly<TParams>;
|
|
20
|
+
}
|
|
21
|
+
interface BroadcastQueueOptions {
|
|
22
|
+
readonly queued?: boolean;
|
|
23
|
+
readonly connection?: string;
|
|
24
|
+
readonly queue?: string;
|
|
25
|
+
readonly afterCommit?: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface NormalizedBroadcastQueueOptions {
|
|
28
|
+
readonly queued: boolean;
|
|
29
|
+
readonly connection?: string;
|
|
30
|
+
readonly queue?: string;
|
|
31
|
+
readonly afterCommit: boolean;
|
|
32
|
+
}
|
|
33
|
+
interface BroadcastDefinitionInput<TName extends string = string, TPayload extends BroadcastJsonObject = BroadcastJsonObject, TChannels extends readonly BroadcastChannelTarget[] = readonly BroadcastChannelTarget[]> {
|
|
34
|
+
readonly name?: TName;
|
|
35
|
+
readonly channels?: TChannels | (() => TChannels);
|
|
36
|
+
readonly payload?: TPayload | (() => TPayload);
|
|
37
|
+
readonly queue?: boolean | BroadcastQueueOptions;
|
|
38
|
+
readonly delay?: BroadcastDelayValue;
|
|
39
|
+
}
|
|
40
|
+
interface BroadcastDefinition<TName extends string = string, TPayload extends BroadcastJsonObject = BroadcastJsonObject, TChannels extends readonly BroadcastChannelTarget[] = readonly BroadcastChannelTarget[]> {
|
|
41
|
+
readonly name?: TName;
|
|
42
|
+
readonly channels: Readonly<TChannels>;
|
|
43
|
+
readonly payload: Readonly<TPayload>;
|
|
44
|
+
readonly queue: NormalizedBroadcastQueueOptions;
|
|
45
|
+
readonly delay?: BroadcastDelayValue;
|
|
46
|
+
}
|
|
47
|
+
type ExportedBroadcastDefinition<TValue> = Extract<TValue, BroadcastDefinition> extends never ? BroadcastDefinition : Extract<TValue, BroadcastDefinition>;
|
|
48
|
+
type BroadcastAuthorizeResult<TType extends BroadcastChannelType, TPresenceMember extends BroadcastJsonObject> = TType extends 'presence' ? false | TPresenceMember : boolean;
|
|
49
|
+
type BroadcastWhisperSchema = ValidationSchema;
|
|
50
|
+
type BroadcastWhisperDefinitions = Readonly<Record<string, BroadcastWhisperSchema>>;
|
|
51
|
+
type InferBroadcastWhisperPayload<TSchema> = TSchema extends {
|
|
52
|
+
readonly $data?: infer TData;
|
|
53
|
+
} ? TData : never;
|
|
54
|
+
interface ChannelDefinitionInput<TPattern extends string = string, TType extends Extract<BroadcastChannelType, 'private' | 'presence'> = Extract<BroadcastChannelType, 'private' | 'presence'>, TUser = unknown, TPresenceMember extends BroadcastJsonObject = BroadcastJsonObject, TWhispers extends BroadcastWhisperDefinitions = BroadcastWhisperDefinitions> {
|
|
55
|
+
readonly type: TType;
|
|
56
|
+
readonly authorize: (user: TUser, params: ChannelPatternParams<TPattern>) => BroadcastAuthorizeResult<TType, TPresenceMember> | Promise<BroadcastAuthorizeResult<TType, TPresenceMember>>;
|
|
57
|
+
readonly whispers?: TWhispers;
|
|
58
|
+
}
|
|
59
|
+
interface ChannelDefinition<TPattern extends string = string, TType extends Extract<BroadcastChannelType, 'private' | 'presence'> = Extract<BroadcastChannelType, 'private' | 'presence'>, TUser = unknown, TPresenceMember extends BroadcastJsonObject = BroadcastJsonObject, TWhispers extends BroadcastWhisperDefinitions = BroadcastWhisperDefinitions> {
|
|
60
|
+
readonly pattern: TPattern;
|
|
61
|
+
readonly type: TType;
|
|
62
|
+
readonly authorize: ChannelDefinitionInput<TPattern, TType, TUser, TPresenceMember, TWhispers>['authorize'];
|
|
63
|
+
readonly whispers: Readonly<TWhispers>;
|
|
64
|
+
}
|
|
65
|
+
type ExportedChannelDefinition<TValue> = Extract<TValue, ChannelDefinition> extends never ? ChannelDefinition : Extract<TValue, ChannelDefinition>;
|
|
66
|
+
interface RawBroadcastSendInput<TPayload extends BroadcastJsonObject = BroadcastJsonObject> {
|
|
67
|
+
readonly connection?: string;
|
|
68
|
+
readonly event: string;
|
|
69
|
+
readonly channels: readonly string[];
|
|
70
|
+
readonly payload: Readonly<TPayload>;
|
|
71
|
+
readonly socketId?: string;
|
|
72
|
+
}
|
|
73
|
+
interface ResolvedRawBroadcastSendInput<TPayload extends BroadcastJsonObject = BroadcastJsonObject> {
|
|
74
|
+
readonly connection: string;
|
|
75
|
+
readonly event: string;
|
|
76
|
+
readonly channels: readonly string[];
|
|
77
|
+
readonly payload: Readonly<TPayload>;
|
|
78
|
+
readonly socketId?: string;
|
|
79
|
+
}
|
|
80
|
+
interface BroadcastSendResult {
|
|
81
|
+
readonly connection: string;
|
|
82
|
+
readonly driver: string;
|
|
83
|
+
readonly queued: boolean;
|
|
84
|
+
readonly publishedChannels: readonly string[];
|
|
85
|
+
readonly messageId?: string;
|
|
86
|
+
readonly provider?: Readonly<Record<string, unknown>>;
|
|
87
|
+
}
|
|
88
|
+
interface BroadcastDispatchOptions {
|
|
89
|
+
readonly broadcaster?: string;
|
|
90
|
+
readonly connection?: string;
|
|
91
|
+
readonly queue?: string;
|
|
92
|
+
readonly delay?: BroadcastDelayValue;
|
|
93
|
+
readonly afterCommit?: boolean;
|
|
94
|
+
}
|
|
95
|
+
interface BroadcastSendInput {
|
|
96
|
+
readonly broadcast: BroadcastDefinition;
|
|
97
|
+
readonly raw: ResolvedRawBroadcastSendInput;
|
|
98
|
+
readonly options: Readonly<BroadcastDispatchOptions>;
|
|
99
|
+
}
|
|
100
|
+
interface BroadcastRuntimeBindings {
|
|
101
|
+
readonly config?: NormalizedHoloBroadcastConfig;
|
|
102
|
+
publish?(input: ResolvedRawBroadcastSendInput, context: BroadcastDriverExecutionContext): BroadcastSendResult | Promise<BroadcastSendResult>;
|
|
103
|
+
readonly channelAuth?: BroadcastChannelAuthRuntimeBindings;
|
|
104
|
+
}
|
|
105
|
+
interface BroadcastRuntimeFacade {
|
|
106
|
+
broadcast(definition: BroadcastDefinition | BroadcastDefinitionInput): PendingBroadcastDispatch<BroadcastSendResult>;
|
|
107
|
+
broadcastRaw(input: RawBroadcastSendInput): PendingBroadcastDispatch<BroadcastSendResult>;
|
|
108
|
+
}
|
|
109
|
+
interface PendingBroadcastDispatch<TResult = BroadcastSendResult> extends PromiseLike<TResult> {
|
|
110
|
+
using(name: string): PendingBroadcastDispatch<TResult>;
|
|
111
|
+
onConnection(name: string): PendingBroadcastDispatch<TResult>;
|
|
112
|
+
onQueue(name: string): PendingBroadcastDispatch<TResult>;
|
|
113
|
+
delay(value: BroadcastDelayValue): PendingBroadcastDispatch<TResult>;
|
|
114
|
+
afterCommit(): PendingBroadcastDispatch<TResult>;
|
|
115
|
+
then<TResult1 = TResult, TResult2 = never>(onfulfilled?: ((value: TResult) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
116
|
+
catch<TResult1 = never>(onrejected?: ((reason: unknown) => TResult1 | PromiseLike<TResult1>) | null): Promise<TResult | TResult1>;
|
|
117
|
+
finally(onfinally?: (() => void) | null): Promise<TResult>;
|
|
118
|
+
}
|
|
119
|
+
interface BroadcastDriverExecutionContext {
|
|
120
|
+
readonly connection: string;
|
|
121
|
+
readonly driver: string;
|
|
122
|
+
readonly queued: boolean;
|
|
123
|
+
readonly delayed: boolean;
|
|
124
|
+
}
|
|
125
|
+
interface BroadcastDriver {
|
|
126
|
+
send(input: ResolvedRawBroadcastSendInput, context: BroadcastDriverExecutionContext): BroadcastSendResult | Promise<BroadcastSendResult>;
|
|
127
|
+
}
|
|
128
|
+
interface RegisterBroadcastDriverOptions {
|
|
129
|
+
readonly replace?: boolean;
|
|
130
|
+
}
|
|
131
|
+
interface RegisteredBroadcastDriver {
|
|
132
|
+
readonly name: string;
|
|
133
|
+
readonly driver: BroadcastDriver;
|
|
134
|
+
}
|
|
135
|
+
interface BuiltInBroadcastDriverRegistry {
|
|
136
|
+
readonly holo: BroadcastDriver;
|
|
137
|
+
readonly pusher: BroadcastDriver;
|
|
138
|
+
readonly ably: BroadcastDriver;
|
|
139
|
+
readonly log: BroadcastDriver;
|
|
140
|
+
readonly null: BroadcastDriver;
|
|
141
|
+
}
|
|
142
|
+
interface HoloBroadcastDriverRegistry {
|
|
143
|
+
}
|
|
144
|
+
interface HoloBroadcastRegistry {
|
|
145
|
+
}
|
|
146
|
+
interface HoloChannelRegistry {
|
|
147
|
+
}
|
|
148
|
+
type BroadcastDriverName = keyof BuiltInBroadcastDriverRegistry | keyof HoloBroadcastDriverRegistry | (string & {});
|
|
149
|
+
interface GeneratedChannelAuthRegistryEntry {
|
|
150
|
+
readonly sourcePath: string;
|
|
151
|
+
readonly pattern: string;
|
|
152
|
+
readonly exportName?: string;
|
|
153
|
+
readonly type: 'private' | 'presence';
|
|
154
|
+
readonly params: readonly string[];
|
|
155
|
+
readonly whispers: readonly string[];
|
|
156
|
+
}
|
|
157
|
+
interface BroadcastChannelAuthRuntimeBindings {
|
|
158
|
+
readonly definitions?: Readonly<Record<string, ChannelDefinition>> | readonly ChannelDefinition[];
|
|
159
|
+
readonly registry?: {
|
|
160
|
+
readonly projectRoot: string;
|
|
161
|
+
readonly channels: readonly GeneratedChannelAuthRegistryEntry[];
|
|
162
|
+
};
|
|
163
|
+
readonly resolveUser?: (connection: {
|
|
164
|
+
readonly headers: Headers;
|
|
165
|
+
readonly socketId: string;
|
|
166
|
+
readonly channel: string;
|
|
167
|
+
readonly appId: string;
|
|
168
|
+
readonly connection: string;
|
|
169
|
+
}) => unknown | Promise<unknown>;
|
|
170
|
+
readonly importModule?: (absolutePath: string) => Promise<unknown>;
|
|
171
|
+
}
|
|
172
|
+
interface BroadcastChannelAuthRequest {
|
|
173
|
+
readonly channel: string;
|
|
174
|
+
readonly socketId?: string;
|
|
175
|
+
readonly user: unknown;
|
|
176
|
+
}
|
|
177
|
+
interface BroadcastChannelAuthSuccess {
|
|
178
|
+
readonly ok: true;
|
|
179
|
+
readonly channel: string;
|
|
180
|
+
readonly type: 'private' | 'presence';
|
|
181
|
+
readonly pattern: string;
|
|
182
|
+
readonly params: Readonly<Record<string, string>>;
|
|
183
|
+
readonly whispers: readonly string[];
|
|
184
|
+
readonly member?: Readonly<BroadcastJsonObject>;
|
|
185
|
+
}
|
|
186
|
+
interface BroadcastChannelAuthFailure {
|
|
187
|
+
readonly ok: false;
|
|
188
|
+
readonly channel: string;
|
|
189
|
+
readonly code: 'unauthorized' | 'not-found';
|
|
190
|
+
}
|
|
191
|
+
type BroadcastChannelAuthResult = BroadcastChannelAuthSuccess | BroadcastChannelAuthFailure;
|
|
192
|
+
interface BroadcastAuthEndpointPayload {
|
|
193
|
+
readonly channel: string;
|
|
194
|
+
readonly socketId?: string;
|
|
195
|
+
}
|
|
196
|
+
interface BroadcastAuthEndpointSuccessBody {
|
|
197
|
+
readonly ok: true;
|
|
198
|
+
readonly channel: string;
|
|
199
|
+
readonly type: 'private' | 'presence';
|
|
200
|
+
readonly params: Readonly<Record<string, string>>;
|
|
201
|
+
readonly whispers: readonly string[];
|
|
202
|
+
readonly member?: Readonly<BroadcastJsonObject>;
|
|
203
|
+
}
|
|
204
|
+
interface BroadcastAuthEndpointErrorBody {
|
|
205
|
+
readonly ok: false;
|
|
206
|
+
readonly error: 'invalid-request' | 'unauthenticated' | 'not-found' | 'unauthorized' | 'method-not-allowed';
|
|
207
|
+
readonly message: string;
|
|
208
|
+
}
|
|
209
|
+
type BroadcastAuthEndpointBody = BroadcastAuthEndpointSuccessBody | BroadcastAuthEndpointErrorBody;
|
|
210
|
+
interface BroadcastAuthEndpointOptions {
|
|
211
|
+
readonly user?: unknown;
|
|
212
|
+
readonly resolveUser?: (request: Request) => unknown | Promise<unknown>;
|
|
213
|
+
readonly channelAuth?: BroadcastChannelAuthRuntimeBindings;
|
|
214
|
+
}
|
|
215
|
+
interface BroadcastWhisperValidationResult<TPayload extends BroadcastJsonObject = BroadcastJsonObject> {
|
|
216
|
+
readonly channel: string;
|
|
217
|
+
readonly event: string;
|
|
218
|
+
readonly payload: Readonly<TPayload>;
|
|
219
|
+
}
|
|
220
|
+
type KnownBroadcastName = Extract<keyof HoloBroadcastRegistry, string>;
|
|
221
|
+
type KnownChannelPattern = Extract<keyof HoloChannelRegistry, string>;
|
|
222
|
+
type BroadcastPayloadFor<TName extends string> = TName extends KnownBroadcastName ? HoloBroadcastRegistry[TName] extends BroadcastDefinition<string, infer TPayload, readonly BroadcastChannelTarget[]> ? TPayload : BroadcastJsonObject : BroadcastJsonObject;
|
|
223
|
+
type BroadcastChannelsFor<TName extends string> = TName extends KnownBroadcastName ? HoloBroadcastRegistry[TName] extends BroadcastDefinition<string, BroadcastJsonObject, infer TChannels> ? TChannels : readonly BroadcastChannelTarget[] : readonly BroadcastChannelTarget[];
|
|
224
|
+
type ChannelDefinitionFor<TPattern extends string> = TPattern extends KnownChannelPattern ? HoloChannelRegistry[TPattern] extends ChannelDefinition ? HoloChannelRegistry[TPattern] : ChannelDefinition : ChannelDefinition;
|
|
225
|
+
type ChannelPresenceMemberFor<TPattern extends string> = ChannelDefinitionFor<TPattern> extends ChannelDefinition<string, 'presence', unknown, infer TPresenceMember, BroadcastWhisperDefinitions> ? TPresenceMember : never;
|
|
226
|
+
type ChannelWhisperPayloadFor<TPattern extends string, TName extends string> = ChannelDefinitionFor<TPattern> extends ChannelDefinition<string, Extract<BroadcastChannelType, 'private' | 'presence'>, unknown, BroadcastJsonObject, infer TWhispers> ? TName extends keyof TWhispers ? InferBroadcastWhisperPayload<TWhispers[TName]> : never : never;
|
|
227
|
+
interface GeneratedBroadcastManifestEvent {
|
|
228
|
+
readonly name: string;
|
|
229
|
+
readonly channels: readonly {
|
|
230
|
+
readonly type: BroadcastChannelType;
|
|
231
|
+
readonly pattern: string;
|
|
232
|
+
}[];
|
|
233
|
+
}
|
|
234
|
+
interface GeneratedBroadcastManifestChannel {
|
|
235
|
+
readonly name: string;
|
|
236
|
+
readonly pattern: string;
|
|
237
|
+
readonly type: Extract<BroadcastChannelType, 'private' | 'presence'>;
|
|
238
|
+
readonly params: readonly string[];
|
|
239
|
+
readonly whispers: readonly string[];
|
|
240
|
+
readonly member?: Readonly<BroadcastJsonObject>;
|
|
241
|
+
}
|
|
242
|
+
interface GeneratedBroadcastManifest {
|
|
243
|
+
readonly version: 1;
|
|
244
|
+
readonly generatedAt: string;
|
|
245
|
+
readonly events: readonly GeneratedBroadcastManifestEvent[];
|
|
246
|
+
readonly channels: readonly GeneratedBroadcastManifestChannel[];
|
|
247
|
+
}
|
|
248
|
+
declare function isReadonlyArray(value: unknown): value is readonly unknown[];
|
|
249
|
+
declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
250
|
+
declare function normalizeDelayValue(value: BroadcastDelayValue | undefined): BroadcastDelayValue | undefined;
|
|
251
|
+
declare function normalizeJsonValue(value: unknown, path: string): BroadcastJsonValue;
|
|
252
|
+
declare function normalizeQueueOptions(queue: boolean | BroadcastQueueOptions | undefined): NormalizedBroadcastQueueOptions;
|
|
253
|
+
declare function extractChannelPatternParamNames(pattern: string): readonly string[];
|
|
254
|
+
declare function normalizeChannelPattern(pattern: string, label?: string): string;
|
|
255
|
+
declare function formatChannelPattern<TPattern extends string>(pattern: TPattern, params: ChannelPatternParams<TPattern>): string;
|
|
256
|
+
declare function normalizeWhisperDefinitions<TWhispers extends BroadcastWhisperDefinitions | undefined>(whispers: TWhispers): Readonly<TWhispers extends BroadcastWhisperDefinitions ? TWhispers : BroadcastWhisperDefinitions>;
|
|
257
|
+
declare function isBroadcastChannelTarget(value: unknown): value is BroadcastChannelTarget;
|
|
258
|
+
declare function isBroadcastDefinition(value: unknown): value is BroadcastDefinition;
|
|
259
|
+
declare function isChannelDefinition(value: unknown): value is ChannelDefinition;
|
|
260
|
+
declare function normalizeBroadcastDefinition<TName extends string, TPayload extends BroadcastJsonObject, TChannels extends readonly BroadcastChannelTarget[]>(definition: BroadcastDefinitionInput<TName, TPayload, TChannels>): BroadcastDefinition<TName, TPayload, TChannels>;
|
|
261
|
+
declare function defineBroadcast<TName extends string, TPayload extends BroadcastJsonObject, TChannels extends readonly BroadcastChannelTarget[]>(definition: BroadcastDefinitionInput<TName, TPayload, TChannels>): BroadcastDefinition<TName, TPayload, TChannels>;
|
|
262
|
+
declare function normalizeChannelDefinition<TPattern extends string, TType extends Extract<BroadcastChannelType, 'private' | 'presence'>, TUser, TPresenceMember extends BroadcastJsonObject, TWhispers extends BroadcastWhisperDefinitions>(pattern: TPattern, definition: ChannelDefinitionInput<TPattern, TType, TUser, TPresenceMember, TWhispers>): ChannelDefinition<TPattern, TType, TUser, TPresenceMember, TWhispers>;
|
|
263
|
+
declare function defineChannel<TPattern extends string, TType extends Extract<BroadcastChannelType, 'private' | 'presence'>, TUser, TPresenceMember extends BroadcastJsonObject, TWhispers extends BroadcastWhisperDefinitions>(pattern: TPattern, definition: ChannelDefinitionInput<TPattern, TType, TUser, TPresenceMember, TWhispers>): ChannelDefinition<TPattern, TType, TUser, TPresenceMember, TWhispers>;
|
|
264
|
+
declare function channel<TPattern extends string>(pattern: TPattern, params?: BroadcastTargetParamInput): BroadcastChannelTarget<'public', TPattern>;
|
|
265
|
+
declare function privateChannel<TPattern extends string>(pattern: TPattern, params?: BroadcastTargetParamInput): BroadcastChannelTarget<'private', TPattern>;
|
|
266
|
+
declare function presenceChannel<TPattern extends string>(pattern: TPattern, params?: BroadcastTargetParamInput): BroadcastChannelTarget<'presence', TPattern>;
|
|
267
|
+
type InferChannelPresenceMember<TChannel> = TChannel extends ChannelDefinition<string, 'presence', unknown, infer TPresenceMember, BroadcastWhisperDefinitions> ? TPresenceMember : never;
|
|
268
|
+
type InferChannelWhisperPayload<TChannel, TName extends string> = TChannel extends ChannelDefinition<string, Extract<BroadcastChannelType, 'private' | 'presence'>, unknown, BroadcastJsonObject, infer TWhispers> ? TName extends keyof TWhispers ? InferBroadcastWhisperPayload<TWhispers[TName]> : never : never;
|
|
269
|
+
type InferSchemaOutput<TSchema extends ValidationSchema> = InferSchemaData<TSchema['fields']>;
|
|
270
|
+
declare const broadcastInternals: {
|
|
271
|
+
extractChannelPatternParamNames: typeof extractChannelPatternParamNames;
|
|
272
|
+
formatChannelPattern: typeof formatChannelPattern;
|
|
273
|
+
hasBroadcastDefinitionMarker(value: unknown): boolean;
|
|
274
|
+
hasChannelDefinitionMarker(value: unknown): boolean;
|
|
275
|
+
isBroadcastChannelTarget: typeof isBroadcastChannelTarget;
|
|
276
|
+
isPlainObject: typeof isPlainObject;
|
|
277
|
+
isReadonlyArray: typeof isReadonlyArray;
|
|
278
|
+
normalizeBroadcastDefinition: typeof normalizeBroadcastDefinition;
|
|
279
|
+
normalizeChannelDefinition: typeof normalizeChannelDefinition;
|
|
280
|
+
normalizeChannelPattern: typeof normalizeChannelPattern;
|
|
281
|
+
normalizeDelayValue: typeof normalizeDelayValue;
|
|
282
|
+
normalizeJsonValue: typeof normalizeJsonValue;
|
|
283
|
+
normalizeQueueOptions: typeof normalizeQueueOptions;
|
|
284
|
+
normalizeWhisperDefinitions: typeof normalizeWhisperDefinitions;
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
export { type BroadcastAuthEndpointBody, type BroadcastAuthEndpointErrorBody, type BroadcastAuthEndpointOptions, type BroadcastAuthEndpointPayload, type BroadcastAuthEndpointSuccessBody, type BroadcastAuthorizeResult, type BroadcastChannelAuthFailure, type BroadcastChannelAuthRequest, type BroadcastChannelAuthResult, type BroadcastChannelAuthRuntimeBindings, type BroadcastChannelAuthSuccess, type BroadcastChannelTarget, type BroadcastChannelType, type BroadcastChannelsFor, type BroadcastDefinition, type BroadcastDefinitionInput, type BroadcastDelayValue, type BroadcastDispatchOptions, type BroadcastDriver, type BroadcastDriverExecutionContext, type BroadcastDriverName, type BroadcastJsonObject, type BroadcastJsonPrimitive, type BroadcastJsonValue, type BroadcastPayloadFor, type BroadcastQueueOptions, type BroadcastRuntimeBindings, type BroadcastRuntimeFacade, type BroadcastSendInput, type BroadcastSendResult, type BroadcastTargetParamInput, type BroadcastWhisperDefinitions, type BroadcastWhisperSchema, type BroadcastWhisperValidationResult, type BuiltInBroadcastDriverRegistry, type ChannelDefinition, type ChannelDefinitionFor, type ChannelDefinitionInput, type ChannelPatternParams, type ChannelPresenceMemberFor, type ChannelWhisperPayloadFor, type ExportedBroadcastDefinition, type ExportedChannelDefinition, type GeneratedBroadcastManifest, type GeneratedBroadcastManifestChannel, type GeneratedBroadcastManifestEvent, type GeneratedChannelAuthRegistryEntry, type HoloBroadcastDriverRegistry, type HoloBroadcastRegistry, type HoloChannelRegistry, type InferBroadcastWhisperPayload, type InferChannelPresenceMember, type InferChannelWhisperPayload, type InferSchemaOutput, type NormalizedBroadcastQueueOptions, type PendingBroadcastDispatch, type RawBroadcastSendInput, type RegisterBroadcastDriverOptions, type RegisteredBroadcastDriver, type ResolvedRawBroadcastSendInput, broadcastInternals, channel, defineBroadcast, defineChannel, extractChannelPatternParamNames, formatChannelPattern, isBroadcastChannelTarget, isBroadcastDefinition, isChannelDefinition, normalizeBroadcastDefinition, normalizeChannelDefinition, normalizeChannelPattern, presenceChannel, privateChannel };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
broadcastInternals,
|
|
3
|
+
channel,
|
|
4
|
+
defineBroadcast,
|
|
5
|
+
defineChannel,
|
|
6
|
+
extractChannelPatternParamNames,
|
|
7
|
+
formatChannelPattern,
|
|
8
|
+
isBroadcastChannelTarget,
|
|
9
|
+
isBroadcastDefinition,
|
|
10
|
+
isChannelDefinition,
|
|
11
|
+
normalizeBroadcastDefinition,
|
|
12
|
+
normalizeChannelDefinition,
|
|
13
|
+
normalizeChannelPattern,
|
|
14
|
+
presenceChannel,
|
|
15
|
+
privateChannel
|
|
16
|
+
} from "./chunk-QW6MHEWS.mjs";
|
|
17
|
+
export {
|
|
18
|
+
broadcastInternals,
|
|
19
|
+
channel,
|
|
20
|
+
defineBroadcast,
|
|
21
|
+
defineChannel,
|
|
22
|
+
extractChannelPatternParamNames,
|
|
23
|
+
formatChannelPattern,
|
|
24
|
+
isBroadcastChannelTarget,
|
|
25
|
+
isBroadcastDefinition,
|
|
26
|
+
isChannelDefinition,
|
|
27
|
+
normalizeBroadcastDefinition,
|
|
28
|
+
normalizeChannelDefinition,
|
|
29
|
+
normalizeChannelPattern,
|
|
30
|
+
presenceChannel,
|
|
31
|
+
privateChannel
|
|
32
|
+
};
|