@rlanz/socket 0.0.1-5 → 0.0.1-6
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 +12 -13
- package/build/{chunk-ANT2E3LT.js → chunk-FVPY6HZW.js} +1 -1
- package/build/chunk-FVPY6HZW.js.map +1 -0
- package/build/{framework-CvxgHwbv.d.ts → framework-DuW6zpPk.d.ts} +4 -2
- package/build/index.d.ts +3 -3
- package/build/providers/socket_provider.d.ts +2 -2
- package/build/providers/socket_provider.js +6 -0
- package/build/providers/socket_provider.js.map +1 -1
- package/build/services/socket.d.ts +2 -2
- package/build/{socket_service-mybqv1hj.d.ts → socket_service-D3jKrleE.d.ts} +1 -1
- package/build/src/assembler_hook.d.ts +6 -4
- package/build/src/assembler_hook.js +16 -4
- package/build/src/assembler_hook.js.map +1 -1
- package/build/src/client/index.d.ts +1 -1
- package/build/src/client/react.d.ts +2 -2
- package/build/src/client/react.js +1 -1
- package/build/src/client/svelte.d.ts +5 -4
- package/build/src/client/svelte.js +1 -1
- package/build/src/client/svelte.js.map +1 -1
- package/build/src/client/types.d.ts +4 -3
- package/build/src/client/vue.d.ts +5 -4
- package/build/src/client/vue.js +1 -1
- package/build/src/client/vue.js.map +1 -1
- package/build/src/decorators.d.ts +1 -1
- package/build/src/health_check.d.ts +2 -2
- package/build/src/types.d.ts +1 -1
- package/build/{types-C7Q36ryo.d.ts → types-DiYaFvgi.d.ts} +4 -0
- package/package.json +1 -1
- package/build/chunk-ANT2E3LT.js.map +0 -1
|
@@ -4,10 +4,12 @@ interface SocketAssemblerHookOptions {
|
|
|
4
4
|
source?: string;
|
|
5
5
|
glob?: string[];
|
|
6
6
|
output?: string;
|
|
7
|
-
importAlias?: string;
|
|
8
7
|
}
|
|
8
|
+
type SocketAssemblerHook = Extract<CommonHooks['init'][number], {
|
|
9
|
+
run: (...args: any[]) => any;
|
|
10
|
+
}>;
|
|
9
11
|
/** Registers generation of the application socket registry with AdonisJS Assembler. */
|
|
10
|
-
declare function generateSocketRegistry(options?: SocketAssemblerHookOptions):
|
|
11
|
-
declare const
|
|
12
|
+
declare function generateSocketRegistry(options?: SocketAssemblerHookOptions): SocketAssemblerHook;
|
|
13
|
+
declare const lazySocketRegistryHook: SocketAssemblerHook['run'];
|
|
12
14
|
|
|
13
|
-
export { type SocketAssemblerHookOptions,
|
|
15
|
+
export { type SocketAssemblerHookOptions, lazySocketRegistryHook as default, generateSocketRegistry };
|
|
@@ -4,6 +4,15 @@ import ts from "typescript";
|
|
|
4
4
|
function quote(value) {
|
|
5
5
|
return `'${value.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'`;
|
|
6
6
|
}
|
|
7
|
+
function generatedImportPath(importPath) {
|
|
8
|
+
return importPath.replace(/\.ts$/, "");
|
|
9
|
+
}
|
|
10
|
+
function appImportAlias(source) {
|
|
11
|
+
const normalized = source.replace(/^\.\//, "");
|
|
12
|
+
if (normalized === "app") return "#app";
|
|
13
|
+
if (normalized.startsWith("app/")) return `#app/${normalized.slice("app/".length)}`;
|
|
14
|
+
throw new Error("[socket] Channel source must be inside the app directory");
|
|
15
|
+
}
|
|
7
16
|
function fail(filePath, message) {
|
|
8
17
|
throw new Error(`[socket] Cannot generate client types for ${filePath}: ${message}`);
|
|
9
18
|
}
|
|
@@ -180,7 +189,7 @@ function generateSocketRegistry(options = {}) {
|
|
|
180
189
|
run(_parent, hooks, indexGenerator) {
|
|
181
190
|
const source = options.source ?? "./app/channels";
|
|
182
191
|
const glob = options.glob ?? ["**/*_channel.{ts,js}"];
|
|
183
|
-
const importAlias =
|
|
192
|
+
const importAlias = appImportAlias(source);
|
|
184
193
|
indexGenerator.add("socketChannels", {
|
|
185
194
|
source,
|
|
186
195
|
glob,
|
|
@@ -190,7 +199,8 @@ function generateSocketRegistry(options = {}) {
|
|
|
190
199
|
const channels = [];
|
|
191
200
|
const diagnostics = [];
|
|
192
201
|
for (const filePath of Object.values(vfs.asList())) {
|
|
193
|
-
const
|
|
202
|
+
const importPath = generatedImportPath(helpers.toImportPath(filePath));
|
|
203
|
+
const inspected = inspectChannel(filePath, importPath);
|
|
194
204
|
if (typeof inspected === "string") diagnostics.push(inspected);
|
|
195
205
|
else channels.push(inspected);
|
|
196
206
|
}
|
|
@@ -226,7 +236,8 @@ function generateSocketRegistry(options = {}) {
|
|
|
226
236
|
as(vfs, buffer, _config, helpers) {
|
|
227
237
|
const filePaths = Object.values(vfs.asList());
|
|
228
238
|
filePaths.forEach((filePath, index) => {
|
|
229
|
-
|
|
239
|
+
const importPath = generatedImportPath(helpers.toImportPath(filePath));
|
|
240
|
+
buffer.writeLine(`import Channel${index} from ${quote(importPath)}`);
|
|
230
241
|
});
|
|
231
242
|
if (filePaths.length) buffer.writeLine("");
|
|
232
243
|
buffer.writeLine(
|
|
@@ -241,7 +252,8 @@ function generateSocketRegistry(options = {}) {
|
|
|
241
252
|
};
|
|
242
253
|
}
|
|
243
254
|
var socketRegistryHook = generateSocketRegistry();
|
|
244
|
-
var
|
|
255
|
+
var lazySocketRegistryHook = socketRegistryHook.run;
|
|
256
|
+
var assembler_hook_default = lazySocketRegistryHook;
|
|
245
257
|
export {
|
|
246
258
|
assembler_hook_default as default,
|
|
247
259
|
generateSocketRegistry
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/assembler_hook.ts"],"sourcesContent":["import fs from 'node:fs'\nimport ts from 'typescript'\nimport type { CommonHooks } from '@adonisjs/assembler/types'\nimport type { IndexGeneratorSourceConfig } from '@adonisjs/assembler/types'\n\nexport interface SocketAssemblerHookOptions {\n source?: string\n glob?: string[]\n output?: string\n importAlias?: string\n}\n\ntype Handler = { event: string; method: string }\ntype Channel = { pattern: string; importPath: string; handlers: Handler[] }\n\nfunction quote(value: string) {\n return `'${value.replaceAll('\\\\', '\\\\\\\\').replaceAll(\"'\", \"\\\\'\")}'`\n}\n\nfunction fail(filePath: string, message: string): never {\n throw new Error(`[socket] Cannot generate client types for ${filePath}: ${message}`)\n}\n\nfunction propertyName(node: ts.PropertyName | undefined): string | undefined {\n if (node && (ts.isIdentifier(node) || ts.isStringLiteral(node))) return node.text\n}\n\nfunction isPublic(method: ts.MethodDeclaration) {\n return !method.modifiers?.some(\n (modifier) =>\n modifier.kind === ts.SyntaxKind.PrivateKeyword ||\n modifier.kind === ts.SyntaxKind.ProtectedKeyword\n )\n}\n\nfunction isStatic(member: ts.ClassElement): boolean {\n return (\n ts.canHaveModifiers(member) &&\n !!ts.getModifiers(member)?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword)\n )\n}\n\nfunction validateHandlerMethod(filePath: string, method: ts.MethodDeclaration, name: string): void {\n const parameters = method.parameters.filter(\n (parameter) => !(ts.isIdentifier(parameter.name) && parameter.name.text === 'this')\n )\n if (parameters.some((parameter) => parameter.dotDotDotToken)) {\n fail(filePath, `handler method ${name} must not use rest parameters`)\n }\n if (parameters.slice(2).some((parameter) => !parameter.questionToken && !parameter.initializer)) {\n fail(filePath, `handler method ${name} must not require parameters after the payload`)\n }\n}\n\nfunction isSupportedPattern(pattern: string): boolean {\n const normalized = pattern === '/' ? '/' : pattern.replace(/^\\//, '').replace(/\\/$/, '')\n if (normalized === '/') {\n return true\n }\n const segments = normalized.split('/')\n\n return segments.every((segment, index) => {\n const isFinal = index === segments.length - 1\n const literal = segment.length > 0 && !/[:*?]/.test(segment)\n const requiredParam = /^:[^.:?/*]+$/.test(segment)\n const optionalParam = /^:[^.:?/*]+\\?$/.test(segment)\n\n return literal || requiredParam || (isFinal && (optionalParam || segment === '*'))\n })\n}\n\nfunction inspectChannel(filePath: string, importPath: string): Channel | string {\n const source = ts.createSourceFile(\n filePath,\n fs.readFileSync(filePath, 'utf8'),\n ts.ScriptTarget.Latest,\n true,\n filePath.endsWith('.js') ? ts.ScriptKind.JS : ts.ScriptKind.TS\n )\n const decoratorImports = new Set<string>()\n const decoratorNamespaces = new Set<string>()\n const baseChannelImports = new Set<string>()\n const socketNamespaces = new Set<string>()\n\n for (const statement of source.statements) {\n if (\n !ts.isImportDeclaration(statement) ||\n !ts.isStringLiteral(statement.moduleSpecifier) ||\n (statement.moduleSpecifier.text !== '@rlanz/socket/decorators' &&\n statement.moduleSpecifier.text !== '@rlanz/socket')\n ) {\n continue\n }\n\n const bindings = statement.importClause?.namedBindings\n if (bindings && ts.isNamedImports(bindings)) {\n for (const binding of bindings.elements) {\n const importedName = (binding.propertyName ?? binding.name).text\n if (\n statement.moduleSpecifier.text === '@rlanz/socket/decorators' &&\n importedName === 'onMessage'\n ) {\n decoratorImports.add(binding.name.text)\n }\n if (statement.moduleSpecifier.text === '@rlanz/socket' && importedName === 'BaseChannel') {\n baseChannelImports.add(binding.name.text)\n }\n }\n } else if (bindings && ts.isNamespaceImport(bindings)) {\n if (statement.moduleSpecifier.text === '@rlanz/socket/decorators') {\n decoratorNamespaces.add(bindings.name.text)\n } else {\n socketNamespaces.add(bindings.name.text)\n }\n }\n }\n\n const classes = source.statements.filter(ts.isClassDeclaration)\n let channelClass = classes.find((node) =>\n node.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword)\n )\n\n if (!channelClass) {\n const defaultExport = source.statements.find(\n (node): node is ts.ExportAssignment => ts.isExportAssignment(node) && !node.isExportEquals\n )\n if (defaultExport && ts.isIdentifier(defaultExport.expression)) {\n const defaultClassName = defaultExport.expression.text\n channelClass = classes.find((node) => node.name?.text === defaultClassName)\n }\n }\n if (!channelClass) fail(filePath, 'a default-exported channel class was not found')\n if (channelClass.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.AbstractKeyword)) {\n fail(filePath, 'the default-exported channel class must not be abstract')\n }\n\n const extendsType = channelClass.heritageClauses\n ?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)\n ?.types.at(0)\n const extendsExpression = extendsType?.expression\n const directlyExtendsBaseChannel =\n (extendsExpression &&\n ts.isIdentifier(extendsExpression) &&\n baseChannelImports.has(extendsExpression.text)) ||\n (extendsExpression &&\n ts.isPropertyAccessExpression(extendsExpression) &&\n ts.isIdentifier(extendsExpression.expression) &&\n socketNamespaces.has(extendsExpression.expression.text) &&\n extendsExpression.name.text === 'BaseChannel')\n\n if (!directlyExtendsBaseChannel) {\n return (\n `Omitted ${importPath}: generated contracts do not support channel inheritance; ` +\n 'the default export must directly extend BaseChannel imported from @rlanz/socket.'\n )\n }\n\n const patternMember = channelClass.members.find(\n (member): member is ts.PropertyDeclaration =>\n ts.isPropertyDeclaration(member) &&\n propertyName(member.name) === 'pattern' &&\n !!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword)\n )\n if (\n !patternMember ||\n !patternMember.initializer ||\n !ts.isStringLiteral(patternMember.initializer)\n ) {\n return `Omitted ${importPath}: static pattern must be a direct string literal.`\n }\n\n if (!isSupportedPattern(patternMember.initializer.text)) {\n return (\n `Omitted ${importPath}: pattern ${quote(patternMember.initializer.text)} is not supported by ` +\n 'generated typing; use literals, required params, a final optional param, or a final wildcard.'\n )\n }\n\n const methods = new Map<string, ts.MethodDeclaration>()\n for (const member of channelClass.members) {\n if (ts.isMethodDeclaration(member) && !isStatic(member)) {\n const name = propertyName(member.name)\n if (name) methods.set(name, member)\n }\n }\n\n const handlers: Handler[] = []\n const handlerMember = channelClass.members.find(\n (member): member is ts.PropertyDeclaration =>\n ts.isPropertyDeclaration(member) &&\n !isStatic(member) &&\n propertyName(member.name) === 'handlers'\n )\n if (handlerMember) {\n if (!handlerMember.initializer || !ts.isObjectLiteralExpression(handlerMember.initializer)) {\n fail(filePath, 'handlers must be an object literal')\n }\n for (const property of handlerMember.initializer.properties) {\n if (!ts.isPropertyAssignment(property) || !ts.isStringLiteral(property.name)) {\n fail(filePath, 'handler event keys must be direct string literals')\n }\n const event = property.name.text\n const value = property.initializer\n if (\n !ts.isPropertyAccessExpression(value) ||\n value.expression.kind !== ts.SyntaxKind.ThisKeyword ||\n !ts.isIdentifier(value.name)\n ) {\n fail(filePath, `handler \"${event}\" must reference this.<publicMethod>`)\n }\n const method = methods.get(value.name.text)\n if (!method) fail(filePath, `handler \"${event}\" references missing method ${value.name.text}`)\n if (!isPublic(method)) {\n fail(filePath, `handler method ${value.name.text} must be public`)\n }\n validateHandlerMethod(filePath, method, value.name.text)\n if (handlers.some((handler) => handler.event === event)) {\n fail(filePath, `event \"${event}\" is mapped more than once`)\n }\n handlers.push({ event, method: value.name.text })\n }\n }\n\n for (const method of channelClass.members.filter(ts.isMethodDeclaration)) {\n for (const decorator of ts.getDecorators(method) ?? []) {\n const expression = decorator.expression\n const isImportedDecorator =\n ts.isCallExpression(expression) &&\n ((ts.isIdentifier(expression.expression) &&\n decoratorImports.has(expression.expression.text)) ||\n (ts.isPropertyAccessExpression(expression.expression) &&\n ts.isIdentifier(expression.expression.expression) &&\n decoratorNamespaces.has(expression.expression.expression.text) &&\n expression.expression.name.text === 'onMessage'))\n\n if (!isImportedDecorator || !ts.isCallExpression(expression)) {\n continue\n }\n\n if (isStatic(method)) {\n fail(filePath, '@onMessage cannot generate a contract for a static method')\n }\n\n if (expression.arguments.length !== 1 || !ts.isStringLiteral(expression.arguments[0])) {\n fail(\n filePath,\n `@onMessage on ${propertyName(method.name) ?? '<computed>'} needs a literal event`\n )\n }\n const event = expression.arguments[0].text\n const name = propertyName(method.name)\n if (!name || !ts.isIdentifier(method.name)) fail(filePath, '@onMessage methods must be named')\n if (!isPublic(method)) fail(filePath, `decorated handler method ${name} must be public`)\n validateHandlerMethod(filePath, method, name)\n if (handlers.some((handler) => handler.event === event)) {\n fail(filePath, `event \"${event}\" is mapped more than once`)\n }\n handlers.push({ event, method: name })\n }\n }\n\n return { pattern: patternMember.initializer.text, importPath, handlers }\n}\n\n/** Registers generation of the application socket registry with AdonisJS Assembler. */\nexport function generateSocketRegistry(\n options: SocketAssemblerHookOptions = {}\n): CommonHooks['init'][number] {\n return {\n run(_parent, hooks, indexGenerator) {\n const source = options.source ?? './app/channels'\n const glob = options.glob ?? ['**/*_channel.{ts,js}']\n const importAlias = options.importAlias\n\n indexGenerator.add('socketChannels', {\n source,\n glob,\n importAlias,\n output: options.output ?? './.adonisjs/client/socket.ts',\n as(vfs, buffer, _config, helpers) {\n const channels: Channel[] = []\n const diagnostics: string[] = []\n for (const filePath of Object.values(vfs.asList())) {\n const inspected = inspectChannel(filePath, helpers.toImportPath(filePath))\n if (typeof inspected === 'string') diagnostics.push(inspected)\n else channels.push(inspected)\n }\n\n for (const diagnostic of diagnostics) buffer.writeLine(`// [socket] ${diagnostic}`)\n if (diagnostics.length) buffer.writeLine('')\n buffer.writeLine('export interface AppSocket {').indent()\n if (diagnostics.length) {\n buffer.writeLine('readonly uncertain: true')\n }\n buffer.writeLine('readonly channels: readonly [').indent()\n for (const channel of channels) {\n buffer.writeLine('{').indent()\n buffer.writeLine(`readonly pattern: ${quote(channel.pattern)}`)\n buffer.writeLine(\n `readonly channel: typeof import(${quote(channel.importPath)}).default`\n )\n buffer.writeLine('readonly handlers: {').indent()\n for (const handler of channel.handlers) {\n buffer.writeLine(`readonly ${quote(handler.event)}: ${quote(handler.method)}`)\n }\n buffer.dedent().writeLine('}')\n buffer.dedent().writeLine('},')\n }\n buffer.dedent().writeLine(']')\n buffer.dedent().writeLine('}')\n },\n } satisfies IndexGeneratorSourceConfig)\n\n indexGenerator.add('socketServerChannels', {\n source,\n glob,\n importAlias,\n output: './.adonisjs/server/socket_channels.ts',\n as(vfs, buffer, _config, helpers) {\n const filePaths = Object.values(vfs.asList())\n filePaths.forEach((filePath, index) => {\n buffer.writeLine(`import Channel${index} from ${quote(helpers.toImportPath(filePath))}`)\n })\n if (filePaths.length) buffer.writeLine('')\n buffer.writeLine(\n `export const socketChannels = [${filePaths.map((_filePath, index) => `Channel${index}`).join(', ')}] as const`\n )\n },\n } satisfies IndexGeneratorSourceConfig)\n\n hooks.add('fileChanged', (_relativePath, absolutePath) => {\n return indexGenerator.addFile(absolutePath)\n })\n },\n }\n}\n\nconst socketRegistryHook: CommonHooks['init'][number] = generateSocketRegistry()\n\nexport default socketRegistryHook\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/assembler_hook.ts"],"sourcesContent":["import fs from 'node:fs'\nimport ts from 'typescript'\nimport type { CommonHooks } from '@adonisjs/assembler/types'\nimport type { IndexGeneratorSourceConfig } from '@adonisjs/assembler/types'\n\nexport interface SocketAssemblerHookOptions {\n source?: string\n glob?: string[]\n output?: string\n}\n\ntype Handler = { event: string; method: string }\ntype Channel = { pattern: string; importPath: string; handlers: Handler[] }\ntype SocketAssemblerHook = Extract<CommonHooks['init'][number], { run: (...args: any[]) => any }>\n\nfunction quote(value: string) {\n return `'${value.replaceAll('\\\\', '\\\\\\\\').replaceAll(\"'\", \"\\\\'\")}'`\n}\n\nfunction generatedImportPath(importPath: string): string {\n return importPath.replace(/\\.ts$/, '')\n}\n\nfunction appImportAlias(source: string): string {\n const normalized = source.replace(/^\\.\\//, '')\n if (normalized === 'app') return '#app'\n if (normalized.startsWith('app/')) return `#app/${normalized.slice('app/'.length)}`\n throw new Error('[socket] Channel source must be inside the app directory')\n}\n\nfunction fail(filePath: string, message: string): never {\n throw new Error(`[socket] Cannot generate client types for ${filePath}: ${message}`)\n}\n\nfunction propertyName(node: ts.PropertyName | undefined): string | undefined {\n if (node && (ts.isIdentifier(node) || ts.isStringLiteral(node))) return node.text\n}\n\nfunction isPublic(method: ts.MethodDeclaration) {\n return !method.modifiers?.some(\n (modifier) =>\n modifier.kind === ts.SyntaxKind.PrivateKeyword ||\n modifier.kind === ts.SyntaxKind.ProtectedKeyword\n )\n}\n\nfunction isStatic(member: ts.ClassElement): boolean {\n return (\n ts.canHaveModifiers(member) &&\n !!ts.getModifiers(member)?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword)\n )\n}\n\nfunction validateHandlerMethod(filePath: string, method: ts.MethodDeclaration, name: string): void {\n const parameters = method.parameters.filter(\n (parameter) => !(ts.isIdentifier(parameter.name) && parameter.name.text === 'this')\n )\n if (parameters.some((parameter) => parameter.dotDotDotToken)) {\n fail(filePath, `handler method ${name} must not use rest parameters`)\n }\n if (parameters.slice(2).some((parameter) => !parameter.questionToken && !parameter.initializer)) {\n fail(filePath, `handler method ${name} must not require parameters after the payload`)\n }\n}\n\nfunction isSupportedPattern(pattern: string): boolean {\n const normalized = pattern === '/' ? '/' : pattern.replace(/^\\//, '').replace(/\\/$/, '')\n if (normalized === '/') {\n return true\n }\n const segments = normalized.split('/')\n\n return segments.every((segment, index) => {\n const isFinal = index === segments.length - 1\n const literal = segment.length > 0 && !/[:*?]/.test(segment)\n const requiredParam = /^:[^.:?/*]+$/.test(segment)\n const optionalParam = /^:[^.:?/*]+\\?$/.test(segment)\n\n return literal || requiredParam || (isFinal && (optionalParam || segment === '*'))\n })\n}\n\nfunction inspectChannel(filePath: string, importPath: string): Channel | string {\n const source = ts.createSourceFile(\n filePath,\n fs.readFileSync(filePath, 'utf8'),\n ts.ScriptTarget.Latest,\n true,\n filePath.endsWith('.js') ? ts.ScriptKind.JS : ts.ScriptKind.TS\n )\n const decoratorImports = new Set<string>()\n const decoratorNamespaces = new Set<string>()\n const baseChannelImports = new Set<string>()\n const socketNamespaces = new Set<string>()\n\n for (const statement of source.statements) {\n if (\n !ts.isImportDeclaration(statement) ||\n !ts.isStringLiteral(statement.moduleSpecifier) ||\n (statement.moduleSpecifier.text !== '@rlanz/socket/decorators' &&\n statement.moduleSpecifier.text !== '@rlanz/socket')\n ) {\n continue\n }\n\n const bindings = statement.importClause?.namedBindings\n if (bindings && ts.isNamedImports(bindings)) {\n for (const binding of bindings.elements) {\n const importedName = (binding.propertyName ?? binding.name).text\n if (\n statement.moduleSpecifier.text === '@rlanz/socket/decorators' &&\n importedName === 'onMessage'\n ) {\n decoratorImports.add(binding.name.text)\n }\n if (statement.moduleSpecifier.text === '@rlanz/socket' && importedName === 'BaseChannel') {\n baseChannelImports.add(binding.name.text)\n }\n }\n } else if (bindings && ts.isNamespaceImport(bindings)) {\n if (statement.moduleSpecifier.text === '@rlanz/socket/decorators') {\n decoratorNamespaces.add(bindings.name.text)\n } else {\n socketNamespaces.add(bindings.name.text)\n }\n }\n }\n\n const classes = source.statements.filter(ts.isClassDeclaration)\n let channelClass = classes.find((node) =>\n node.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword)\n )\n\n if (!channelClass) {\n const defaultExport = source.statements.find(\n (node): node is ts.ExportAssignment => ts.isExportAssignment(node) && !node.isExportEquals\n )\n if (defaultExport && ts.isIdentifier(defaultExport.expression)) {\n const defaultClassName = defaultExport.expression.text\n channelClass = classes.find((node) => node.name?.text === defaultClassName)\n }\n }\n if (!channelClass) fail(filePath, 'a default-exported channel class was not found')\n if (channelClass.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.AbstractKeyword)) {\n fail(filePath, 'the default-exported channel class must not be abstract')\n }\n\n const extendsType = channelClass.heritageClauses\n ?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)\n ?.types.at(0)\n const extendsExpression = extendsType?.expression\n const directlyExtendsBaseChannel =\n (extendsExpression &&\n ts.isIdentifier(extendsExpression) &&\n baseChannelImports.has(extendsExpression.text)) ||\n (extendsExpression &&\n ts.isPropertyAccessExpression(extendsExpression) &&\n ts.isIdentifier(extendsExpression.expression) &&\n socketNamespaces.has(extendsExpression.expression.text) &&\n extendsExpression.name.text === 'BaseChannel')\n\n if (!directlyExtendsBaseChannel) {\n return (\n `Omitted ${importPath}: generated contracts do not support channel inheritance; ` +\n 'the default export must directly extend BaseChannel imported from @rlanz/socket.'\n )\n }\n\n const patternMember = channelClass.members.find(\n (member): member is ts.PropertyDeclaration =>\n ts.isPropertyDeclaration(member) &&\n propertyName(member.name) === 'pattern' &&\n !!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword)\n )\n if (\n !patternMember ||\n !patternMember.initializer ||\n !ts.isStringLiteral(patternMember.initializer)\n ) {\n return `Omitted ${importPath}: static pattern must be a direct string literal.`\n }\n\n if (!isSupportedPattern(patternMember.initializer.text)) {\n return (\n `Omitted ${importPath}: pattern ${quote(patternMember.initializer.text)} is not supported by ` +\n 'generated typing; use literals, required params, a final optional param, or a final wildcard.'\n )\n }\n\n const methods = new Map<string, ts.MethodDeclaration>()\n for (const member of channelClass.members) {\n if (ts.isMethodDeclaration(member) && !isStatic(member)) {\n const name = propertyName(member.name)\n if (name) methods.set(name, member)\n }\n }\n\n const handlers: Handler[] = []\n const handlerMember = channelClass.members.find(\n (member): member is ts.PropertyDeclaration =>\n ts.isPropertyDeclaration(member) &&\n !isStatic(member) &&\n propertyName(member.name) === 'handlers'\n )\n if (handlerMember) {\n if (!handlerMember.initializer || !ts.isObjectLiteralExpression(handlerMember.initializer)) {\n fail(filePath, 'handlers must be an object literal')\n }\n for (const property of handlerMember.initializer.properties) {\n if (!ts.isPropertyAssignment(property) || !ts.isStringLiteral(property.name)) {\n fail(filePath, 'handler event keys must be direct string literals')\n }\n const event = property.name.text\n const value = property.initializer\n if (\n !ts.isPropertyAccessExpression(value) ||\n value.expression.kind !== ts.SyntaxKind.ThisKeyword ||\n !ts.isIdentifier(value.name)\n ) {\n fail(filePath, `handler \"${event}\" must reference this.<publicMethod>`)\n }\n const method = methods.get(value.name.text)\n if (!method) fail(filePath, `handler \"${event}\" references missing method ${value.name.text}`)\n if (!isPublic(method)) {\n fail(filePath, `handler method ${value.name.text} must be public`)\n }\n validateHandlerMethod(filePath, method, value.name.text)\n if (handlers.some((handler) => handler.event === event)) {\n fail(filePath, `event \"${event}\" is mapped more than once`)\n }\n handlers.push({ event, method: value.name.text })\n }\n }\n\n for (const method of channelClass.members.filter(ts.isMethodDeclaration)) {\n for (const decorator of ts.getDecorators(method) ?? []) {\n const expression = decorator.expression\n const isImportedDecorator =\n ts.isCallExpression(expression) &&\n ((ts.isIdentifier(expression.expression) &&\n decoratorImports.has(expression.expression.text)) ||\n (ts.isPropertyAccessExpression(expression.expression) &&\n ts.isIdentifier(expression.expression.expression) &&\n decoratorNamespaces.has(expression.expression.expression.text) &&\n expression.expression.name.text === 'onMessage'))\n\n if (!isImportedDecorator || !ts.isCallExpression(expression)) {\n continue\n }\n\n if (isStatic(method)) {\n fail(filePath, '@onMessage cannot generate a contract for a static method')\n }\n\n if (expression.arguments.length !== 1 || !ts.isStringLiteral(expression.arguments[0])) {\n fail(\n filePath,\n `@onMessage on ${propertyName(method.name) ?? '<computed>'} needs a literal event`\n )\n }\n const event = expression.arguments[0].text\n const name = propertyName(method.name)\n if (!name || !ts.isIdentifier(method.name)) fail(filePath, '@onMessage methods must be named')\n if (!isPublic(method)) fail(filePath, `decorated handler method ${name} must be public`)\n validateHandlerMethod(filePath, method, name)\n if (handlers.some((handler) => handler.event === event)) {\n fail(filePath, `event \"${event}\" is mapped more than once`)\n }\n handlers.push({ event, method: name })\n }\n }\n\n return { pattern: patternMember.initializer.text, importPath, handlers }\n}\n\n/** Registers generation of the application socket registry with AdonisJS Assembler. */\nexport function generateSocketRegistry(\n options: SocketAssemblerHookOptions = {}\n): SocketAssemblerHook {\n return {\n run(_parent, hooks, indexGenerator) {\n const source = options.source ?? './app/channels'\n const glob = options.glob ?? ['**/*_channel.{ts,js}']\n const importAlias = appImportAlias(source)\n\n indexGenerator.add('socketChannels', {\n source,\n glob,\n importAlias,\n output: options.output ?? './.adonisjs/client/socket.ts',\n as(vfs, buffer, _config, helpers) {\n const channels: Channel[] = []\n const diagnostics: string[] = []\n for (const filePath of Object.values(vfs.asList())) {\n const importPath = generatedImportPath(helpers.toImportPath(filePath))\n const inspected = inspectChannel(filePath, importPath)\n if (typeof inspected === 'string') diagnostics.push(inspected)\n else channels.push(inspected)\n }\n\n for (const diagnostic of diagnostics) buffer.writeLine(`// [socket] ${diagnostic}`)\n if (diagnostics.length) buffer.writeLine('')\n buffer.writeLine('export interface AppSocket {').indent()\n if (diagnostics.length) {\n buffer.writeLine('readonly uncertain: true')\n }\n buffer.writeLine('readonly channels: readonly [').indent()\n for (const channel of channels) {\n buffer.writeLine('{').indent()\n buffer.writeLine(`readonly pattern: ${quote(channel.pattern)}`)\n buffer.writeLine(\n `readonly channel: typeof import(${quote(channel.importPath)}).default`\n )\n buffer.writeLine('readonly handlers: {').indent()\n for (const handler of channel.handlers) {\n buffer.writeLine(`readonly ${quote(handler.event)}: ${quote(handler.method)}`)\n }\n buffer.dedent().writeLine('}')\n buffer.dedent().writeLine('},')\n }\n buffer.dedent().writeLine(']')\n buffer.dedent().writeLine('}')\n },\n } satisfies IndexGeneratorSourceConfig)\n\n indexGenerator.add('socketServerChannels', {\n source,\n glob,\n importAlias,\n output: './.adonisjs/server/socket_channels.ts',\n as(vfs, buffer, _config, helpers) {\n const filePaths = Object.values(vfs.asList())\n filePaths.forEach((filePath, index) => {\n const importPath = generatedImportPath(helpers.toImportPath(filePath))\n buffer.writeLine(`import Channel${index} from ${quote(importPath)}`)\n })\n if (filePaths.length) buffer.writeLine('')\n buffer.writeLine(\n `export const socketChannels = [${filePaths.map((_filePath, index) => `Channel${index}`).join(', ')}] as const`\n )\n },\n } satisfies IndexGeneratorSourceConfig)\n\n hooks.add('fileChanged', (_relativePath, absolutePath) => {\n return indexGenerator.addFile(absolutePath)\n })\n },\n }\n}\n\nconst socketRegistryHook = generateSocketRegistry()\nconst lazySocketRegistryHook: SocketAssemblerHook['run'] = socketRegistryHook.run\n\nexport default lazySocketRegistryHook\n"],"mappings":";AAAA,OAAO,QAAQ;AACf,OAAO,QAAQ;AAcf,SAAS,MAAM,OAAe;AAC5B,SAAO,IAAI,MAAM,WAAW,MAAM,MAAM,EAAE,WAAW,KAAK,KAAK,CAAC;AAClE;AAEA,SAAS,oBAAoB,YAA4B;AACvD,SAAO,WAAW,QAAQ,SAAS,EAAE;AACvC;AAEA,SAAS,eAAe,QAAwB;AAC9C,QAAM,aAAa,OAAO,QAAQ,SAAS,EAAE;AAC7C,MAAI,eAAe,MAAO,QAAO;AACjC,MAAI,WAAW,WAAW,MAAM,EAAG,QAAO,QAAQ,WAAW,MAAM,OAAO,MAAM,CAAC;AACjF,QAAM,IAAI,MAAM,0DAA0D;AAC5E;AAEA,SAAS,KAAK,UAAkB,SAAwB;AACtD,QAAM,IAAI,MAAM,6CAA6C,QAAQ,KAAK,OAAO,EAAE;AACrF;AAEA,SAAS,aAAa,MAAuD;AAC3E,MAAI,SAAS,GAAG,aAAa,IAAI,KAAK,GAAG,gBAAgB,IAAI,GAAI,QAAO,KAAK;AAC/E;AAEA,SAAS,SAAS,QAA8B;AAC9C,SAAO,CAAC,OAAO,WAAW;AAAA,IACxB,CAAC,aACC,SAAS,SAAS,GAAG,WAAW,kBAChC,SAAS,SAAS,GAAG,WAAW;AAAA,EACpC;AACF;AAEA,SAAS,SAAS,QAAkC;AAClD,SACE,GAAG,iBAAiB,MAAM,KAC1B,CAAC,CAAC,GAAG,aAAa,MAAM,GAAG,KAAK,CAAC,aAAa,SAAS,SAAS,GAAG,WAAW,aAAa;AAE/F;AAEA,SAAS,sBAAsB,UAAkB,QAA8B,MAAoB;AACjG,QAAM,aAAa,OAAO,WAAW;AAAA,IACnC,CAAC,cAAc,EAAE,GAAG,aAAa,UAAU,IAAI,KAAK,UAAU,KAAK,SAAS;AAAA,EAC9E;AACA,MAAI,WAAW,KAAK,CAAC,cAAc,UAAU,cAAc,GAAG;AAC5D,SAAK,UAAU,kBAAkB,IAAI,+BAA+B;AAAA,EACtE;AACA,MAAI,WAAW,MAAM,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,UAAU,iBAAiB,CAAC,UAAU,WAAW,GAAG;AAC/F,SAAK,UAAU,kBAAkB,IAAI,gDAAgD;AAAA,EACvF;AACF;AAEA,SAAS,mBAAmB,SAA0B;AACpD,QAAM,aAAa,YAAY,MAAM,MAAM,QAAQ,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,EAAE;AACvF,MAAI,eAAe,KAAK;AACtB,WAAO;AAAA,EACT;AACA,QAAM,WAAW,WAAW,MAAM,GAAG;AAErC,SAAO,SAAS,MAAM,CAAC,SAAS,UAAU;AACxC,UAAM,UAAU,UAAU,SAAS,SAAS;AAC5C,UAAM,UAAU,QAAQ,SAAS,KAAK,CAAC,QAAQ,KAAK,OAAO;AAC3D,UAAM,gBAAgB,eAAe,KAAK,OAAO;AACjD,UAAM,gBAAgB,iBAAiB,KAAK,OAAO;AAEnD,WAAO,WAAW,iBAAkB,YAAY,iBAAiB,YAAY;AAAA,EAC/E,CAAC;AACH;AAEA,SAAS,eAAe,UAAkB,YAAsC;AAC9E,QAAM,SAAS,GAAG;AAAA,IAChB;AAAA,IACA,GAAG,aAAa,UAAU,MAAM;AAAA,IAChC,GAAG,aAAa;AAAA,IAChB;AAAA,IACA,SAAS,SAAS,KAAK,IAAI,GAAG,WAAW,KAAK,GAAG,WAAW;AAAA,EAC9D;AACA,QAAM,mBAAmB,oBAAI,IAAY;AACzC,QAAM,sBAAsB,oBAAI,IAAY;AAC5C,QAAM,qBAAqB,oBAAI,IAAY;AAC3C,QAAM,mBAAmB,oBAAI,IAAY;AAEzC,aAAW,aAAa,OAAO,YAAY;AACzC,QACE,CAAC,GAAG,oBAAoB,SAAS,KACjC,CAAC,GAAG,gBAAgB,UAAU,eAAe,KAC5C,UAAU,gBAAgB,SAAS,8BAClC,UAAU,gBAAgB,SAAS,iBACrC;AACA;AAAA,IACF;AAEA,UAAM,WAAW,UAAU,cAAc;AACzC,QAAI,YAAY,GAAG,eAAe,QAAQ,GAAG;AAC3C,iBAAW,WAAW,SAAS,UAAU;AACvC,cAAM,gBAAgB,QAAQ,gBAAgB,QAAQ,MAAM;AAC5D,YACE,UAAU,gBAAgB,SAAS,8BACnC,iBAAiB,aACjB;AACA,2BAAiB,IAAI,QAAQ,KAAK,IAAI;AAAA,QACxC;AACA,YAAI,UAAU,gBAAgB,SAAS,mBAAmB,iBAAiB,eAAe;AACxF,6BAAmB,IAAI,QAAQ,KAAK,IAAI;AAAA,QAC1C;AAAA,MACF;AAAA,IACF,WAAW,YAAY,GAAG,kBAAkB,QAAQ,GAAG;AACrD,UAAI,UAAU,gBAAgB,SAAS,4BAA4B;AACjE,4BAAoB,IAAI,SAAS,KAAK,IAAI;AAAA,MAC5C,OAAO;AACL,yBAAiB,IAAI,SAAS,KAAK,IAAI;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,WAAW,OAAO,GAAG,kBAAkB;AAC9D,MAAI,eAAe,QAAQ;AAAA,IAAK,CAAC,SAC/B,KAAK,WAAW,KAAK,CAAC,aAAa,SAAS,SAAS,GAAG,WAAW,cAAc;AAAA,EACnF;AAEA,MAAI,CAAC,cAAc;AACjB,UAAM,gBAAgB,OAAO,WAAW;AAAA,MACtC,CAAC,SAAsC,GAAG,mBAAmB,IAAI,KAAK,CAAC,KAAK;AAAA,IAC9E;AACA,QAAI,iBAAiB,GAAG,aAAa,cAAc,UAAU,GAAG;AAC9D,YAAM,mBAAmB,cAAc,WAAW;AAClD,qBAAe,QAAQ,KAAK,CAAC,SAAS,KAAK,MAAM,SAAS,gBAAgB;AAAA,IAC5E;AAAA,EACF;AACA,MAAI,CAAC,aAAc,MAAK,UAAU,gDAAgD;AAClF,MAAI,aAAa,WAAW,KAAK,CAAC,aAAa,SAAS,SAAS,GAAG,WAAW,eAAe,GAAG;AAC/F,SAAK,UAAU,yDAAyD;AAAA,EAC1E;AAEA,QAAM,cAAc,aAAa,iBAC7B,KAAK,CAAC,WAAW,OAAO,UAAU,GAAG,WAAW,cAAc,GAC9D,MAAM,GAAG,CAAC;AACd,QAAM,oBAAoB,aAAa;AACvC,QAAM,6BACH,qBACC,GAAG,aAAa,iBAAiB,KACjC,mBAAmB,IAAI,kBAAkB,IAAI,KAC9C,qBACC,GAAG,2BAA2B,iBAAiB,KAC/C,GAAG,aAAa,kBAAkB,UAAU,KAC5C,iBAAiB,IAAI,kBAAkB,WAAW,IAAI,KACtD,kBAAkB,KAAK,SAAS;AAEpC,MAAI,CAAC,4BAA4B;AAC/B,WACE,WAAW,UAAU;AAAA,EAGzB;AAEA,QAAM,gBAAgB,aAAa,QAAQ;AAAA,IACzC,CAAC,WACC,GAAG,sBAAsB,MAAM,KAC/B,aAAa,OAAO,IAAI,MAAM,aAC9B,CAAC,CAAC,OAAO,WAAW,KAAK,CAAC,aAAa,SAAS,SAAS,GAAG,WAAW,aAAa;AAAA,EACxF;AACA,MACE,CAAC,iBACD,CAAC,cAAc,eACf,CAAC,GAAG,gBAAgB,cAAc,WAAW,GAC7C;AACA,WAAO,WAAW,UAAU;AAAA,EAC9B;AAEA,MAAI,CAAC,mBAAmB,cAAc,YAAY,IAAI,GAAG;AACvD,WACE,WAAW,UAAU,aAAa,MAAM,cAAc,YAAY,IAAI,CAAC;AAAA,EAG3E;AAEA,QAAM,UAAU,oBAAI,IAAkC;AACtD,aAAW,UAAU,aAAa,SAAS;AACzC,QAAI,GAAG,oBAAoB,MAAM,KAAK,CAAC,SAAS,MAAM,GAAG;AACvD,YAAM,OAAO,aAAa,OAAO,IAAI;AACrC,UAAI,KAAM,SAAQ,IAAI,MAAM,MAAM;AAAA,IACpC;AAAA,EACF;AAEA,QAAM,WAAsB,CAAC;AAC7B,QAAM,gBAAgB,aAAa,QAAQ;AAAA,IACzC,CAAC,WACC,GAAG,sBAAsB,MAAM,KAC/B,CAAC,SAAS,MAAM,KAChB,aAAa,OAAO,IAAI,MAAM;AAAA,EAClC;AACA,MAAI,eAAe;AACjB,QAAI,CAAC,cAAc,eAAe,CAAC,GAAG,0BAA0B,cAAc,WAAW,GAAG;AAC1F,WAAK,UAAU,oCAAoC;AAAA,IACrD;AACA,eAAW,YAAY,cAAc,YAAY,YAAY;AAC3D,UAAI,CAAC,GAAG,qBAAqB,QAAQ,KAAK,CAAC,GAAG,gBAAgB,SAAS,IAAI,GAAG;AAC5E,aAAK,UAAU,mDAAmD;AAAA,MACpE;AACA,YAAM,QAAQ,SAAS,KAAK;AAC5B,YAAM,QAAQ,SAAS;AACvB,UACE,CAAC,GAAG,2BAA2B,KAAK,KACpC,MAAM,WAAW,SAAS,GAAG,WAAW,eACxC,CAAC,GAAG,aAAa,MAAM,IAAI,GAC3B;AACA,aAAK,UAAU,YAAY,KAAK,sCAAsC;AAAA,MACxE;AACA,YAAM,SAAS,QAAQ,IAAI,MAAM,KAAK,IAAI;AAC1C,UAAI,CAAC,OAAQ,MAAK,UAAU,YAAY,KAAK,+BAA+B,MAAM,KAAK,IAAI,EAAE;AAC7F,UAAI,CAAC,SAAS,MAAM,GAAG;AACrB,aAAK,UAAU,kBAAkB,MAAM,KAAK,IAAI,iBAAiB;AAAA,MACnE;AACA,4BAAsB,UAAU,QAAQ,MAAM,KAAK,IAAI;AACvD,UAAI,SAAS,KAAK,CAAC,YAAY,QAAQ,UAAU,KAAK,GAAG;AACvD,aAAK,UAAU,UAAU,KAAK,4BAA4B;AAAA,MAC5D;AACA,eAAS,KAAK,EAAE,OAAO,QAAQ,MAAM,KAAK,KAAK,CAAC;AAAA,IAClD;AAAA,EACF;AAEA,aAAW,UAAU,aAAa,QAAQ,OAAO,GAAG,mBAAmB,GAAG;AACxE,eAAW,aAAa,GAAG,cAAc,MAAM,KAAK,CAAC,GAAG;AACtD,YAAM,aAAa,UAAU;AAC7B,YAAM,sBACJ,GAAG,iBAAiB,UAAU,MAC5B,GAAG,aAAa,WAAW,UAAU,KACrC,iBAAiB,IAAI,WAAW,WAAW,IAAI,KAC9C,GAAG,2BAA2B,WAAW,UAAU,KAClD,GAAG,aAAa,WAAW,WAAW,UAAU,KAChD,oBAAoB,IAAI,WAAW,WAAW,WAAW,IAAI,KAC7D,WAAW,WAAW,KAAK,SAAS;AAE1C,UAAI,CAAC,uBAAuB,CAAC,GAAG,iBAAiB,UAAU,GAAG;AAC5D;AAAA,MACF;AAEA,UAAI,SAAS,MAAM,GAAG;AACpB,aAAK,UAAU,2DAA2D;AAAA,MAC5E;AAEA,UAAI,WAAW,UAAU,WAAW,KAAK,CAAC,GAAG,gBAAgB,WAAW,UAAU,CAAC,CAAC,GAAG;AACrF;AAAA,UACE;AAAA,UACA,iBAAiB,aAAa,OAAO,IAAI,KAAK,YAAY;AAAA,QAC5D;AAAA,MACF;AACA,YAAM,QAAQ,WAAW,UAAU,CAAC,EAAE;AACtC,YAAM,OAAO,aAAa,OAAO,IAAI;AACrC,UAAI,CAAC,QAAQ,CAAC,GAAG,aAAa,OAAO,IAAI,EAAG,MAAK,UAAU,kCAAkC;AAC7F,UAAI,CAAC,SAAS,MAAM,EAAG,MAAK,UAAU,4BAA4B,IAAI,iBAAiB;AACvF,4BAAsB,UAAU,QAAQ,IAAI;AAC5C,UAAI,SAAS,KAAK,CAAC,YAAY,QAAQ,UAAU,KAAK,GAAG;AACvD,aAAK,UAAU,UAAU,KAAK,4BAA4B;AAAA,MAC5D;AACA,eAAS,KAAK,EAAE,OAAO,QAAQ,KAAK,CAAC;AAAA,IACvC;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,cAAc,YAAY,MAAM,YAAY,SAAS;AACzE;AAGO,SAAS,uBACd,UAAsC,CAAC,GAClB;AACrB,SAAO;AAAA,IACL,IAAI,SAAS,OAAO,gBAAgB;AAClC,YAAM,SAAS,QAAQ,UAAU;AACjC,YAAM,OAAO,QAAQ,QAAQ,CAAC,sBAAsB;AACpD,YAAM,cAAc,eAAe,MAAM;AAEzC,qBAAe,IAAI,kBAAkB;AAAA,QACnC;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,QAAQ,UAAU;AAAA,QAC1B,GAAG,KAAK,QAAQ,SAAS,SAAS;AAChC,gBAAM,WAAsB,CAAC;AAC7B,gBAAM,cAAwB,CAAC;AAC/B,qBAAW,YAAY,OAAO,OAAO,IAAI,OAAO,CAAC,GAAG;AAClD,kBAAM,aAAa,oBAAoB,QAAQ,aAAa,QAAQ,CAAC;AACrE,kBAAM,YAAY,eAAe,UAAU,UAAU;AACrD,gBAAI,OAAO,cAAc,SAAU,aAAY,KAAK,SAAS;AAAA,gBACxD,UAAS,KAAK,SAAS;AAAA,UAC9B;AAEA,qBAAW,cAAc,YAAa,QAAO,UAAU,eAAe,UAAU,EAAE;AAClF,cAAI,YAAY,OAAQ,QAAO,UAAU,EAAE;AAC3C,iBAAO,UAAU,8BAA8B,EAAE,OAAO;AACxD,cAAI,YAAY,QAAQ;AACtB,mBAAO,UAAU,0BAA0B;AAAA,UAC7C;AACA,iBAAO,UAAU,+BAA+B,EAAE,OAAO;AACzD,qBAAW,WAAW,UAAU;AAC9B,mBAAO,UAAU,GAAG,EAAE,OAAO;AAC7B,mBAAO,UAAU,qBAAqB,MAAM,QAAQ,OAAO,CAAC,EAAE;AAC9D,mBAAO;AAAA,cACL,mCAAmC,MAAM,QAAQ,UAAU,CAAC;AAAA,YAC9D;AACA,mBAAO,UAAU,sBAAsB,EAAE,OAAO;AAChD,uBAAW,WAAW,QAAQ,UAAU;AACtC,qBAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,CAAC,KAAK,MAAM,QAAQ,MAAM,CAAC,EAAE;AAAA,YAC/E;AACA,mBAAO,OAAO,EAAE,UAAU,GAAG;AAC7B,mBAAO,OAAO,EAAE,UAAU,IAAI;AAAA,UAChC;AACA,iBAAO,OAAO,EAAE,UAAU,GAAG;AAC7B,iBAAO,OAAO,EAAE,UAAU,GAAG;AAAA,QAC/B;AAAA,MACF,CAAsC;AAEtC,qBAAe,IAAI,wBAAwB;AAAA,QACzC;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,GAAG,KAAK,QAAQ,SAAS,SAAS;AAChC,gBAAM,YAAY,OAAO,OAAO,IAAI,OAAO,CAAC;AAC5C,oBAAU,QAAQ,CAAC,UAAU,UAAU;AACrC,kBAAM,aAAa,oBAAoB,QAAQ,aAAa,QAAQ,CAAC;AACrE,mBAAO,UAAU,iBAAiB,KAAK,SAAS,MAAM,UAAU,CAAC,EAAE;AAAA,UACrE,CAAC;AACD,cAAI,UAAU,OAAQ,QAAO,UAAU,EAAE;AACzC,iBAAO;AAAA,YACL,kCAAkC,UAAU,IAAI,CAAC,WAAW,UAAU,UAAU,KAAK,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,UACrG;AAAA,QACF;AAAA,MACF,CAAsC;AAEtC,YAAM,IAAI,eAAe,CAAC,eAAe,iBAAiB;AACxD,eAAO,eAAe,QAAQ,YAAY;AAAA,MAC5C,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,IAAM,qBAAqB,uBAAuB;AAClD,IAAM,yBAAqD,mBAAmB;AAE9E,IAAO,yBAAQ;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ChannelContract, SocketClientTransport, PresenceUser, EventHandler, SubscribeOptions, UnsubscribeOptions, SocketOptions, ConnectionState, ChannelContractFor } from './types.js';
|
|
2
2
|
export { PresenceData, SubscribeAckData, SubscribeResult } from './types.js';
|
|
3
|
-
export { b as ChannelAck, c as ChannelMessage } from '../../types-
|
|
3
|
+
export { b as ChannelAck, c as ChannelMessage } from '../../types-DiYaFvgi.js';
|
|
4
4
|
import 'ws';
|
|
5
5
|
import 'node:http';
|
|
6
6
|
import '@adonisjs/core/types/http';
|
|
@@ -2,8 +2,8 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { Socket } from './index.js';
|
|
4
4
|
import { ConnectionState, EventHandler } from './types.js';
|
|
5
|
-
import { F as FrameworkChannelName, a as FrameworkChannel, b as FrameworkChannelEvent, c as FrameworkChannelEventPayload } from '../../framework-
|
|
6
|
-
import '../../types-
|
|
5
|
+
import { F as FrameworkChannelName, a as FrameworkChannel, b as FrameworkChannelEvent, c as FrameworkChannelEventPayload } from '../../framework-DuW6zpPk.js';
|
|
6
|
+
import '../../types-DiYaFvgi.js';
|
|
7
7
|
import 'ws';
|
|
8
8
|
import 'node:http';
|
|
9
9
|
import '@adonisjs/core/types/http';
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { Readable } from 'svelte/store';
|
|
2
2
|
import { Socket } from './index.js';
|
|
3
3
|
import { ConnectionState, EventHandler } from './types.js';
|
|
4
|
-
import { F as FrameworkChannelName, a as FrameworkChannel, b as FrameworkChannelEvent, c as FrameworkChannelEventPayload } from '../../framework-
|
|
5
|
-
import '../../types-
|
|
4
|
+
import { F as FrameworkChannelName, a as FrameworkChannel, b as FrameworkChannelEvent, c as FrameworkChannelEventPayload } from '../../framework-DuW6zpPk.js';
|
|
5
|
+
import '../../types-DiYaFvgi.js';
|
|
6
6
|
import 'ws';
|
|
7
7
|
import 'node:http';
|
|
8
8
|
import '@adonisjs/core/types/http';
|
|
9
9
|
import '@adonisjs/core/http';
|
|
10
10
|
import '@boringnode/bus/types/main';
|
|
11
11
|
|
|
12
|
+
type ChannelNameInput<Registry, Name extends string> = (Name & FrameworkChannelName<Registry, NoInfer<Name>>) | null | (Readable<Name | null> & Readable<FrameworkChannelName<Registry, NoInfer<Name>> | null>);
|
|
12
13
|
declare function createSocketContext<Registry = never>(): {
|
|
13
14
|
setSocket: (socket: Socket<Registry>, options?: {
|
|
14
15
|
owned?: boolean;
|
|
15
16
|
}) => void;
|
|
16
17
|
useSocket: () => Socket<Registry>;
|
|
17
18
|
useSocketState: () => Readable<ConnectionState>;
|
|
18
|
-
channel: <const Name extends string>(name:
|
|
19
|
-
onChannelEvent: <const Name extends string, Event extends FrameworkChannelEvent<Registry, Name>>(name:
|
|
19
|
+
channel: <const Name extends string>(name: ChannelNameInput<Registry, Name>) => Readable<FrameworkChannel<Registry, Name> | null>;
|
|
20
|
+
onChannelEvent: <const Name extends string, Event extends FrameworkChannelEvent<Registry, Name>>(name: ChannelNameInput<Registry, Name>, event: Event, handler: EventHandler<FrameworkChannelEventPayload<Registry, Name, Event>>) => () => void;
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
export { createSocketContext };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/svelte.ts"],"sourcesContent":["import { getContext, onDestroy, onMount, setContext } from 'svelte'\nimport { readable, type Readable } from 'svelte/store'\nimport type { Socket } from './socket.js'\nimport type { ConnectionState, EventHandler } from './types.js'\nimport {\n acquireChannel,\n acquireSocketOwnership,\n type FrameworkChannel,\n type FrameworkChannelEvent,\n type FrameworkChannelEventPayload,\n type FrameworkChannelName,\n} from './framework.js'\n\ninterface SvelteSocketContext<Registry> {\n socket: Socket<Registry>\n state: Readable<ConnectionState>\n}\n\nfunction isReadable<Value>(value: Value | Readable<Value>): value is Readable<Value> {\n return typeof value === 'object' && value !== null && 'subscribe' in value\n}\n\nexport function createSocketContext<Registry = never>() {\n const key = Symbol('socket')\n\n function setSocket(socket: Socket<Registry>, options: { owned?: boolean } = {}): void {\n const state = readable(socket.state, (set) => socket.onStateChange(set))\n setContext<SvelteSocketContext<Registry>>(key, { socket, state })\n\n if (options.owned) {\n onMount(() => acquireSocketOwnership(socket))\n }\n }\n\n function useContext(): SvelteSocketContext<Registry> {\n const context = getContext<SvelteSocketContext<Registry>>(key)\n if (!context) throw new Error('setSocket must be called by an ancestor')\n return context\n }\n\n function useSocket(): Socket<Registry> {\n return useContext().socket\n }\n\n function useSocketState(): Readable<ConnectionState> {\n return useContext().state\n }\n\n function channel<const Name extends string>(\n name
|
|
1
|
+
{"version":3,"sources":["../../../src/client/svelte.ts"],"sourcesContent":["import { getContext, onDestroy, onMount, setContext } from 'svelte'\nimport { readable, type Readable } from 'svelte/store'\nimport type { Socket } from './socket.js'\nimport type { ConnectionState, EventHandler } from './types.js'\nimport {\n acquireChannel,\n acquireSocketOwnership,\n type FrameworkChannel,\n type FrameworkChannelEvent,\n type FrameworkChannelEventPayload,\n type FrameworkChannelName,\n} from './framework.js'\n\ninterface SvelteSocketContext<Registry> {\n socket: Socket<Registry>\n state: Readable<ConnectionState>\n}\n\ntype ChannelNameInput<Registry, Name extends string> =\n | (Name & FrameworkChannelName<Registry, NoInfer<Name>>)\n | null\n | (Readable<Name | null> & Readable<FrameworkChannelName<Registry, NoInfer<Name>> | null>)\n\nfunction isReadable<Value>(value: Value | Readable<Value>): value is Readable<Value> {\n return typeof value === 'object' && value !== null && 'subscribe' in value\n}\n\nexport function createSocketContext<Registry = never>() {\n const key = Symbol('socket')\n\n function setSocket(socket: Socket<Registry>, options: { owned?: boolean } = {}): void {\n const state = readable(socket.state, (set) => socket.onStateChange(set))\n setContext<SvelteSocketContext<Registry>>(key, { socket, state })\n\n if (options.owned) {\n onMount(() => acquireSocketOwnership(socket))\n }\n }\n\n function useContext(): SvelteSocketContext<Registry> {\n const context = getContext<SvelteSocketContext<Registry>>(key)\n if (!context) throw new Error('setSocket must be called by an ancestor')\n return context\n }\n\n function useSocket(): Socket<Registry> {\n return useContext().socket\n }\n\n function useSocketState(): Readable<ConnectionState> {\n return useContext().state\n }\n\n function channel<const Name extends string>(\n name: ChannelNameInput<Registry, Name>\n ): Readable<FrameworkChannel<Registry, Name> | null> {\n const socket = useSocket()\n return readable<FrameworkChannel<Registry, Name> | null>(null, (set) => {\n let release: (() => void) | undefined\n const acquire = (nextName: FrameworkChannelName<Registry, Name> | null) => {\n release?.()\n release = undefined\n if (nextName === null) {\n set(null)\n return\n }\n const acquired = acquireChannel(socket, nextName)\n release = () => acquired.lease.release()\n set(acquired.channel)\n }\n\n const stopName = isReadable(name) ? name.subscribe(acquire) : (acquire(name), undefined)\n return () => {\n stopName?.()\n release?.()\n }\n })\n }\n\n function onChannelEvent<\n const Name extends string,\n Event extends FrameworkChannelEvent<Registry, Name>,\n >(\n name: ChannelNameInput<Registry, Name>,\n event: Event,\n handler: EventHandler<FrameworkChannelEventPayload<Registry, Name, Event>>\n ): () => void {\n const socket = useSocket()\n let release: (() => void) | undefined\n const acquire = (nextName: FrameworkChannelName<Registry, Name> | null) => {\n release?.()\n release = undefined\n if (nextName === null) return\n const { lease } = acquireChannel(socket, nextName)\n lease.listen(event, handler)\n release = () => lease.release()\n }\n const stopName = isReadable(name) ? name.subscribe(acquire) : (acquire(name), undefined)\n let disposed = false\n const dispose = () => {\n if (disposed) return\n disposed = true\n stopName?.()\n release?.()\n }\n onDestroy(dispose)\n return dispose\n }\n\n return { setSocket, useSocket, useSocketState, channel, onChannelEvent }\n}\n"],"mappings":";;;;;;;AAAA,SAAS,YAAY,WAAW,SAAS,kBAAkB;AAC3D,SAAS,gBAA+B;AAsBxC,SAAS,WAAkB,OAA0D;AACnF,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,eAAe;AACvE;AAEO,SAAS,sBAAwC;AACtD,QAAM,MAAM,uBAAO,QAAQ;AAE3B,WAAS,UAAU,QAA0B,UAA+B,CAAC,GAAS;AACpF,UAAM,QAAQ,SAAS,OAAO,OAAO,CAAC,QAAQ,OAAO,cAAc,GAAG,CAAC;AACvE,eAA0C,KAAK,EAAE,QAAQ,MAAM,CAAC;AAEhE,QAAI,QAAQ,OAAO;AACjB,cAAQ,MAAM,uBAAuB,MAAM,CAAC;AAAA,IAC9C;AAAA,EACF;AAEA,WAAS,aAA4C;AACnD,UAAM,UAAU,WAA0C,GAAG;AAC7D,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,yCAAyC;AACvE,WAAO;AAAA,EACT;AAEA,WAAS,YAA8B;AACrC,WAAO,WAAW,EAAE;AAAA,EACtB;AAEA,WAAS,iBAA4C;AACnD,WAAO,WAAW,EAAE;AAAA,EACtB;AAEA,WAAS,QACP,MACmD;AACnD,UAAM,SAAS,UAAU;AACzB,WAAO,SAAkD,MAAM,CAAC,QAAQ;AACtE,UAAI;AACJ,YAAM,UAAU,CAAC,aAA0D;AACzE,kBAAU;AACV,kBAAU;AACV,YAAI,aAAa,MAAM;AACrB,cAAI,IAAI;AACR;AAAA,QACF;AACA,cAAM,WAAW,eAAe,QAAQ,QAAQ;AAChD,kBAAU,MAAM,SAAS,MAAM,QAAQ;AACvC,YAAI,SAAS,OAAO;AAAA,MACtB;AAEA,YAAM,WAAW,WAAW,IAAI,IAAI,KAAK,UAAU,OAAO,KAAK,QAAQ,IAAI,GAAG;AAC9E,aAAO,MAAM;AACX,mBAAW;AACX,kBAAU;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,WAAS,eAIP,MACA,OACA,SACY;AACZ,UAAM,SAAS,UAAU;AACzB,QAAI;AACJ,UAAM,UAAU,CAAC,aAA0D;AACzE,gBAAU;AACV,gBAAU;AACV,UAAI,aAAa,KAAM;AACvB,YAAM,EAAE,MAAM,IAAI,eAAe,QAAQ,QAAQ;AACjD,YAAM,OAAO,OAAO,OAAO;AAC3B,gBAAU,MAAM,MAAM,QAAQ;AAAA,IAChC;AACA,UAAM,WAAW,WAAW,IAAI,IAAI,KAAK,UAAU,OAAO,KAAK,QAAQ,IAAI,GAAG;AAC9E,QAAI,WAAW;AACf,UAAM,UAAU,MAAM;AACpB,UAAI,SAAU;AACd,iBAAW;AACX,iBAAW;AACX,gBAAU;AAAA,IACZ;AACA,cAAU,OAAO;AACjB,WAAO;AAAA,EACT;AAEA,SAAO,EAAE,WAAW,WAAW,gBAAgB,SAAS,eAAe;AACzE;","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as ChannelServerEventsOf } from '../../types-
|
|
2
|
-
export { b as ChannelAck, c as ChannelMessage } from '../../types-
|
|
1
|
+
import { a as ChannelServerEventsOf } from '../../types-DiYaFvgi.js';
|
|
2
|
+
export { b as ChannelAck, c as ChannelMessage } from '../../types-DiYaFvgi.js';
|
|
3
3
|
import 'ws';
|
|
4
4
|
import 'node:http';
|
|
5
5
|
import '@adonisjs/core/types/http';
|
|
@@ -57,11 +57,12 @@ type ResolveRegistryEntry<Entries extends readonly unknown[], Name extends strin
|
|
|
57
57
|
type RegistryEntries<Registry> = Registry extends {
|
|
58
58
|
readonly channels: infer Entries extends readonly unknown[];
|
|
59
59
|
} ? Entries : [];
|
|
60
|
+
type PotentialMatchCount<Entries extends readonly unknown[], Name extends string, Count extends 0 | 1 | 2 = 0> = Entries extends readonly [infer Current, ...infer Rest] ? true extends MatchesChannelPattern<PatternOf<Current>, Name> ? PotentialMatchCount<Rest, Name, Count extends 0 ? 1 : 2> : PotentialMatchCount<Rest, Name, Count> : Count;
|
|
60
61
|
type ContractOfEntry<Entry> = ChannelContract<ClientContracts<Entry>, ChannelServerEventsOf<ChannelInstance<Entry>>>;
|
|
61
62
|
/** Resolves a literal channel name to its unique most-specific generated contract. */
|
|
62
63
|
type ChannelContractFor<Registry, Name extends string> = string extends Name ? unknown : Registry extends {
|
|
63
64
|
readonly uncertain: true;
|
|
64
|
-
} ? unknown : ResolveRegistryEntry<RegistryEntries<Registry>, Name> extends infer Entry ? unknown extends Entry ? unknown : [Entry] extends [never] ? never : DefinitelyMatchesChannelPattern<PatternOf<Entry>, Name> extends true ? ContractOfEntry<Entry> : unknown : never;
|
|
65
|
+
} ? unknown : ResolveRegistryEntry<RegistryEntries<Registry>, Name> extends infer Entry ? unknown extends Entry ? unknown : [Entry] extends [never] ? never : DefinitelyMatchesChannelPattern<PatternOf<Entry>, Name> extends true ? ContractOfEntry<Entry> : PotentialMatchCount<RegistryEntries<Registry>, Name> extends 1 ? ContractOfEntry<Entry> : unknown : never;
|
|
65
66
|
/**
|
|
66
67
|
* Connection options.
|
|
67
68
|
*/
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { ShallowRef, ComputedRef, MaybeRefOrGetter } from 'vue';
|
|
2
2
|
import { Socket } from './index.js';
|
|
3
3
|
import { ConnectionState, EventHandler } from './types.js';
|
|
4
|
-
import { F as FrameworkChannelName, a as FrameworkChannel, b as FrameworkChannelEvent, c as FrameworkChannelEventPayload } from '../../framework-
|
|
5
|
-
import '../../types-
|
|
4
|
+
import { F as FrameworkChannelName, a as FrameworkChannel, b as FrameworkChannelEvent, c as FrameworkChannelEventPayload } from '../../framework-DuW6zpPk.js';
|
|
5
|
+
import '../../types-DiYaFvgi.js';
|
|
6
6
|
import 'ws';
|
|
7
7
|
import 'node:http';
|
|
8
8
|
import '@adonisjs/core/types/http';
|
|
9
9
|
import '@adonisjs/core/http';
|
|
10
10
|
import '@boringnode/bus/types/main';
|
|
11
11
|
|
|
12
|
+
type ChannelNameInput<Registry, Name extends string> = MaybeRefOrGetter<Name | null> & MaybeRefOrGetter<FrameworkChannelName<Registry, NoInfer<Name>> | null>;
|
|
12
13
|
declare function createSocketComposables<Registry = never>(): {
|
|
13
14
|
provideSocket: (socket: Socket<Registry>, options?: {
|
|
14
15
|
owned?: boolean;
|
|
@@ -18,8 +19,8 @@ declare function createSocketComposables<Registry = never>(): {
|
|
|
18
19
|
state: Readonly<ShallowRef<ConnectionState>>;
|
|
19
20
|
connected: ComputedRef<boolean>;
|
|
20
21
|
};
|
|
21
|
-
useChannel: <const Name extends string>(name:
|
|
22
|
-
useChannelEvent: <const Name extends string, Event extends FrameworkChannelEvent<Registry, Name>>(name:
|
|
22
|
+
useChannel: <const Name extends string>(name: ChannelNameInput<Registry, Name>) => Readonly<ShallowRef<FrameworkChannel<Registry, Name> | null>>;
|
|
23
|
+
useChannelEvent: <const Name extends string, Event extends FrameworkChannelEvent<Registry, Name>>(name: ChannelNameInput<Registry, Name>, event: Event, handler: EventHandler<FrameworkChannelEventPayload<Registry, Name, Event>>) => void;
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
export { createSocketComposables };
|
package/build/src/client/vue.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/vue.ts"],"sourcesContent":["import {\n computed,\n inject,\n onMounted,\n onScopeDispose,\n provide,\n shallowRef,\n toValue,\n watch,\n type ComputedRef,\n type InjectionKey,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from 'vue'\nimport type { Socket } from './socket.js'\nimport type { ConnectionState, EventHandler } from './types.js'\nimport {\n acquireChannel,\n acquireSocketOwnership,\n type FrameworkChannel,\n type FrameworkChannelEvent,\n type FrameworkChannelEventPayload,\n type FrameworkChannelName,\n} from './framework.js'\n\ninterface VueSocketContext<Registry> {\n socket: Socket<Registry>\n state: ShallowRef<ConnectionState>\n}\n\nexport function createSocketComposables<Registry = never>() {\n const key = Symbol('socket') as InjectionKey<VueSocketContext<Registry>>\n\n function provideSocket(socket: Socket<Registry>, options: { owned?: boolean } = {}): void {\n const state = shallowRef(socket.state)\n const stopStateListener = socket.onStateChange((nextState) => {\n state.value = nextState\n })\n provide(key, { socket, state })\n\n let releaseOwnership: (() => void) | undefined\n if (options.owned) onMounted(() => (releaseOwnership = acquireSocketOwnership(socket)))\n onScopeDispose(() => {\n stopStateListener()\n releaseOwnership?.()\n })\n }\n\n function useContext(): VueSocketContext<Registry> {\n const context = inject(key)\n if (!context) throw new Error('provideSocket must be called by an ancestor')\n return context\n }\n\n function useSocket(): Socket<Registry> {\n return useContext().socket\n }\n\n function useSocketState(): {\n state: Readonly<ShallowRef<ConnectionState>>\n connected: ComputedRef<boolean>\n } {\n const state = useContext().state\n return { state, connected: computed(() => state.value === 'connected') }\n }\n\n function useChannel<const Name extends string>(\n name:
|
|
1
|
+
{"version":3,"sources":["../../../src/client/vue.ts"],"sourcesContent":["import {\n computed,\n inject,\n onMounted,\n onScopeDispose,\n provide,\n shallowRef,\n toValue,\n watch,\n type ComputedRef,\n type InjectionKey,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from 'vue'\nimport type { Socket } from './socket.js'\nimport type { ConnectionState, EventHandler } from './types.js'\nimport {\n acquireChannel,\n acquireSocketOwnership,\n type FrameworkChannel,\n type FrameworkChannelEvent,\n type FrameworkChannelEventPayload,\n type FrameworkChannelName,\n} from './framework.js'\n\ninterface VueSocketContext<Registry> {\n socket: Socket<Registry>\n state: ShallowRef<ConnectionState>\n}\n\ntype ChannelNameInput<Registry, Name extends string> = MaybeRefOrGetter<Name | null> &\n MaybeRefOrGetter<FrameworkChannelName<Registry, NoInfer<Name>> | null>\n\nexport function createSocketComposables<Registry = never>() {\n const key = Symbol('socket') as InjectionKey<VueSocketContext<Registry>>\n\n function provideSocket(socket: Socket<Registry>, options: { owned?: boolean } = {}): void {\n const state = shallowRef(socket.state)\n const stopStateListener = socket.onStateChange((nextState) => {\n state.value = nextState\n })\n provide(key, { socket, state })\n\n let releaseOwnership: (() => void) | undefined\n if (options.owned) onMounted(() => (releaseOwnership = acquireSocketOwnership(socket)))\n onScopeDispose(() => {\n stopStateListener()\n releaseOwnership?.()\n })\n }\n\n function useContext(): VueSocketContext<Registry> {\n const context = inject(key)\n if (!context) throw new Error('provideSocket must be called by an ancestor')\n return context\n }\n\n function useSocket(): Socket<Registry> {\n return useContext().socket\n }\n\n function useSocketState(): {\n state: Readonly<ShallowRef<ConnectionState>>\n connected: ComputedRef<boolean>\n } {\n const state = useContext().state\n return { state, connected: computed(() => state.value === 'connected') }\n }\n\n function useChannel<const Name extends string>(\n name: ChannelNameInput<Registry, Name>\n ): Readonly<ShallowRef<FrameworkChannel<Registry, Name> | null>> {\n const socket = useSocket()\n const channel = shallowRef(null) as ShallowRef<FrameworkChannel<Registry, Name> | null>\n\n watch(\n () => toValue(name),\n (nextName, _previousName, onCleanup) => {\n if (nextName === null) {\n channel.value = null\n return\n }\n const acquired = acquireChannel(socket, nextName as FrameworkChannelName<Registry, Name>)\n channel.value = acquired.channel\n onCleanup(() => acquired.lease.release())\n },\n { immediate: true }\n )\n\n return channel\n }\n\n function useChannelEvent<\n const Name extends string,\n Event extends FrameworkChannelEvent<Registry, Name>,\n >(\n name: ChannelNameInput<Registry, Name>,\n event: Event,\n handler: EventHandler<FrameworkChannelEventPayload<Registry, Name, Event>>\n ): void {\n const socket = useSocket()\n watch(\n () => toValue(name),\n (nextName, _previousName, onCleanup) => {\n if (nextName === null) return\n const { lease } = acquireChannel(socket, nextName as FrameworkChannelName<Registry, Name>)\n lease.listen(event, handler)\n onCleanup(() => lease.release())\n },\n { immediate: true }\n )\n }\n\n return { provideSocket, useSocket, useSocketState, useChannel, useChannelEvent }\n}\n"],"mappings":";;;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AAoBA,SAAS,0BAA4C;AAC1D,QAAM,MAAM,uBAAO,QAAQ;AAE3B,WAAS,cAAc,QAA0B,UAA+B,CAAC,GAAS;AACxF,UAAM,QAAQ,WAAW,OAAO,KAAK;AACrC,UAAM,oBAAoB,OAAO,cAAc,CAAC,cAAc;AAC5D,YAAM,QAAQ;AAAA,IAChB,CAAC;AACD,YAAQ,KAAK,EAAE,QAAQ,MAAM,CAAC;AAE9B,QAAI;AACJ,QAAI,QAAQ,MAAO,WAAU,MAAO,mBAAmB,uBAAuB,MAAM,CAAE;AACtF,mBAAe,MAAM;AACnB,wBAAkB;AAClB,yBAAmB;AAAA,IACrB,CAAC;AAAA,EACH;AAEA,WAAS,aAAyC;AAChD,UAAM,UAAU,OAAO,GAAG;AAC1B,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,6CAA6C;AAC3E,WAAO;AAAA,EACT;AAEA,WAAS,YAA8B;AACrC,WAAO,WAAW,EAAE;AAAA,EACtB;AAEA,WAAS,iBAGP;AACA,UAAM,QAAQ,WAAW,EAAE;AAC3B,WAAO,EAAE,OAAO,WAAW,SAAS,MAAM,MAAM,UAAU,WAAW,EAAE;AAAA,EACzE;AAEA,WAAS,WACP,MAC+D;AAC/D,UAAM,SAAS,UAAU;AACzB,UAAM,UAAU,WAAW,IAAI;AAE/B;AAAA,MACE,MAAM,QAAQ,IAAI;AAAA,MAClB,CAAC,UAAU,eAAe,cAAc;AACtC,YAAI,aAAa,MAAM;AACrB,kBAAQ,QAAQ;AAChB;AAAA,QACF;AACA,cAAM,WAAW,eAAe,QAAQ,QAAgD;AACxF,gBAAQ,QAAQ,SAAS;AACzB,kBAAU,MAAM,SAAS,MAAM,QAAQ,CAAC;AAAA,MAC1C;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,IACpB;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,gBAIP,MACA,OACA,SACM;AACN,UAAM,SAAS,UAAU;AACzB;AAAA,MACE,MAAM,QAAQ,IAAI;AAAA,MAClB,CAAC,UAAU,eAAe,cAAc;AACtC,YAAI,aAAa,KAAM;AACvB,cAAM,EAAE,MAAM,IAAI,eAAe,QAAQ,QAAgD;AACzF,cAAM,OAAO,OAAO,OAAO;AAC3B,kBAAU,MAAM,MAAM,QAAQ,CAAC;AAAA,MACjC;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SAAO,EAAE,eAAe,WAAW,gBAAgB,YAAY,gBAAgB;AACjF;","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BaseCheck, Result } from '@adonisjs/core/health';
|
|
2
|
-
import { S as SocketService } from '../socket_service-
|
|
2
|
+
import { S as SocketService } from '../socket_service-D3jKrleE.js';
|
|
3
3
|
import 'node:http';
|
|
4
4
|
import '@adonisjs/logger';
|
|
5
5
|
import 'emittery';
|
|
6
6
|
import 'ws';
|
|
7
|
-
import '../types-
|
|
7
|
+
import '../types-DiYaFvgi.js';
|
|
8
8
|
import '@adonisjs/core/types/http';
|
|
9
9
|
import '@adonisjs/core/http';
|
|
10
10
|
import '@boringnode/bus/types/main';
|
package/build/src/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AuthenticatedSocket, b as ChannelAck, f as ChannelHandlerFn, C as ChannelHandlerMap, g as ChannelMatch, c as ChannelMessage, h as ChannelOptions, a as ChannelServerEventsOf, D as Duration, M as Middleware, i as MiddlewareClass, j as MiddlewareContext, k as MiddlewareFn, l as PresenceInfo, m as PresenceMember, R as RawSocket, d as SocketAuthenticationHandler, n as SocketAuthenticationResult, S as SocketConfig, o as SocketEvents, p as SocketHealthSnapshot, q as SocketHttpMiddleware, s as SocketServiceStatus, t as SocketUpgradeContext } from '../types-
|
|
1
|
+
export { A as AuthenticatedSocket, b as ChannelAck, f as ChannelHandlerFn, C as ChannelHandlerMap, g as ChannelMatch, c as ChannelMessage, h as ChannelOptions, a as ChannelServerEventsOf, D as Duration, M as Middleware, i as MiddlewareClass, j as MiddlewareContext, k as MiddlewareFn, l as PresenceInfo, m as PresenceMember, R as RawSocket, d as SocketAuthenticationHandler, n as SocketAuthenticationResult, S as SocketConfig, o as SocketEvents, p as SocketHealthSnapshot, q as SocketHttpMiddleware, s as SocketServiceStatus, t as SocketUpgradeContext } from '../types-DiYaFvgi.js';
|
|
2
2
|
import 'ws';
|
|
3
3
|
import 'node:http';
|
|
4
4
|
import '@adonisjs/core/types/http';
|
|
@@ -280,6 +280,10 @@ interface AuthenticatedSocket<User = unknown> {
|
|
|
280
280
|
* Authenticated user resolved during the HTTP upgrade.
|
|
281
281
|
*/
|
|
282
282
|
user: User | undefined;
|
|
283
|
+
/**
|
|
284
|
+
* Returns the authenticated user or throws a client-safe unauthorized error.
|
|
285
|
+
*/
|
|
286
|
+
getUserOrFail(): User;
|
|
283
287
|
/**
|
|
284
288
|
* Emits an event to this socket.
|
|
285
289
|
*/
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/framework.ts"],"sourcesContent":["import type { Channel } from './channel.js'\nimport type { Socket } from './socket.js'\nimport type { ChannelContract, ChannelContractFor, EventHandler } from './types.js'\nimport { callClientHandler } from './callback.js'\n\ntype AnySocket = Socket<any>\ntype UnknownContract = ChannelContract<unknown, unknown>\ntype ServerEvents<Contract> =\n Contract extends ChannelContract<unknown, infer Events> ? Events : unknown\ntype IsUnknown<Value> = unknown extends Value ? true : false\n\nexport type FrameworkChannel<Registry, Name extends string> = string extends Name\n ? Channel<UnknownContract>\n : [Registry] extends [never]\n ? Channel<UnknownContract>\n : ChannelContractFor<Registry, Name> extends infer Contract\n ? [Contract] extends [never]\n ? never\n : Channel<Contract>\n : never\n\nexport type FrameworkChannelName<Registry, Name extends string> = Name &\n (FrameworkChannel<Registry, Name> extends never ? never : unknown)\n\nexport type FrameworkChannelEvent<Registry, Name extends string> =\n FrameworkChannel<Registry, Name> extends Channel<infer Contract>\n ? IsUnknown<ServerEvents<Contract>> extends true\n ? string\n : Extract<keyof ServerEvents<Contract>, string>\n : never\n\nexport type FrameworkChannelEventPayload<\n Registry,\n Name extends string,\n Event extends FrameworkChannelEvent<Registry, Name>,\n> =\n FrameworkChannel<Registry, Name> extends Channel<infer Contract>\n ? IsUnknown<ServerEvents<Contract>> extends true\n ? unknown\n : Event extends keyof ServerEvents<Contract>\n ? ServerEvents<Contract>[Event]\n : never\n : never\n\ninterface ManagedEvent {\n handlers: Set<EventHandler<any>>\n dispatch: EventHandler<any>\n}\n\ninterface ManagedEntry {\n channel: Channel<any>\n socket: AnySocket\n leases: Set<ChannelLease>\n events: Map<string, ManagedEvent>\n lifecycle: { ready: Promise<Channel<any>>; release: () => Promise<void> } | undefined\n}\n\nconst socketEntries = new WeakMap<AnySocket, Map<string, ManagedEntry>>()\nconst socketOwners = new WeakMap<AnySocket, { count: number; generation: number }>()\n\nfunction reportSubscriptionError(error: unknown): void {\n queueMicrotask(() => {\n console.error(error)\n })\n}\n\nfunction attachEvents(entry: ManagedEntry): void {\n for (const [event, managed] of entry.events) {\n entry.channel.$listen(event, managed.dispatch)\n }\n}\n\nfunction getEntry(socket: AnySocket, name: string): ManagedEntry {\n let entries = socketEntries.get(socket)\n if (!entries) {\n entries = new Map()\n socketEntries.set(socket, entries)\n }\n\n const channel = socket.channel(name)\n let entry = entries.get(name)\n if (!entry || entry.channel !== channel) {\n entry = {\n channel,\n socket,\n leases: new Set(),\n events: new Map(),\n lifecycle: undefined,\n }\n entries.set(name, entry)\n }\n\n return entry\n}\n\nexport class ChannelLease {\n readonly entry: ManagedEntry\n #released = false\n #listeners: Array<{ event: string; handler: EventHandler<any> }> = []\n\n constructor(entry: ManagedEntry) {\n this.entry = entry\n }\n\n listen(event: string, handler: EventHandler<any>): void {\n if (this.#released) return\n\n let managed = this.entry.events.get(event)\n if (!managed) {\n const handlers = new Set<EventHandler<any>>()\n managed = {\n handlers,\n dispatch: (data) => {\n for (const listener of handlers) callClientHandler(listener, data)\n },\n }\n this.entry.events.set(event, managed)\n this.entry.channel.$listen(event, managed.dispatch)\n }\n const registration: EventHandler<any> = (data) => handler(data)\n managed.handlers.add(registration)\n this.#listeners.push({ event, handler: registration })\n }\n\n release(): void {\n if (this.#released) return\n this.#released = true\n\n for (const { event, handler } of this.#listeners) {\n const managed = this.entry.events.get(event)\n managed?.handlers.delete(handler)\n if (managed?.handlers.size === 0) {\n this.entry.channel.$stopListening(event, managed.dispatch)\n this.entry.events.delete(event)\n }\n }\n this.#listeners = []\n this.entry.leases.delete(this)\n\n queueMicrotask(() => {\n if (this.entry.leases.size > 0) return\n const lifecycle = this.entry.lifecycle\n this.entry.lifecycle = undefined\n void lifecycle?.release().then(() => {\n if (this.entry.leases.size > 0 || this.entry.lifecycle) return\n const entries = socketEntries.get(this.entry.socket)\n if (entries?.get(this.entry.channel.name) === this.entry) {\n entries.delete(this.entry.channel.name)\n }\n })\n })\n }\n}\n\nexport function acquireChannel<Registry, const Name extends string>(\n socket: Socket<Registry>,\n name: FrameworkChannelName<Registry, Name>\n): { channel: FrameworkChannel<Registry, Name>; lease: ChannelLease } {\n const entry = getEntry(socket, name)\n const lease = new ChannelLease(entry)\n entry.leases.add(lease)\n\n if (!entry.lifecycle) {\n const lifecycle = entry.channel.$acquire()\n entry.lifecycle = lifecycle\n attachEvents(entry)\n void lifecycle.ready\n .then(() => {\n if (entry.lifecycle === lifecycle) attachEvents(entry)\n })\n .catch((error) => {\n if (entry.lifecycle === lifecycle && entry.leases.size > 0 && entry.socket.connected) {\n reportSubscriptionError(error)\n }\n })\n }\n\n return { channel: entry.channel as FrameworkChannel<Registry, Name>, lease }\n}\n\n/** Connects an exclusively owned socket and coalesces development-mode remounts. */\nexport function acquireSocketOwnership(socket: AnySocket): () => void {\n let owner = socketOwners.get(socket)\n if (!owner) {\n owner = { count: 0, generation: 0 }\n socketOwners.set(socket, owner)\n socket.connect().catch(reportSubscriptionError)\n }\n owner.count++\n owner.generation++\n\n let released = false\n return () => {\n if (released) return\n released = true\n owner.count--\n const generation = ++owner.generation\n queueMicrotask(() => {\n if (owner.count === 0 && owner.generation === generation) {\n socket.disconnect()\n socketOwners.delete(socket)\n }\n })\n }\n}\n"],"mappings":"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","names":[]}
|