@rljson/io 0.0.62 → 0.0.63
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/conformance-tests/goldens/tableCfgs-1.json +3 -157
- package/dist/conformance-tests/io-conformance.spec.ts +5 -4
- package/dist/index.d.ts +2 -0
- package/dist/io-multi.d.ts +5 -4
- package/dist/io-peer-bridge.d.ts +75 -0
- package/dist/io.js +391 -52
- package/dist/io.js.map +1 -0
- package/dist/peer-socket-mock.d.ts +13 -0
- package/dist/socket.d.ts +3 -1
- package/package.json +10 -10
package/dist/io.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io.js","sources":["/Users/maximilianheller/Documents/Development/rljson-io/src/io-db-name-mapping.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/io-tools.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/io-mem.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/peer-socket-mock.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/io-peer.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/io-multi.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/io-peer-bridge.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/io-server.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/io-test-setup.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/io.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/reverse-ref.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/socket-mock.ts","/Users/maximilianheller/Documents/Development/rljson-io/src/socket.ts"],"sourcesContent":["// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nexport class IoDbNameMapping {\n // The primary key column is always named '_hash'\n public primaryKeyColumn: string = '_hash';\n public dataSection: string = '_data';\n public typeColumn: string = 'type';\n public keyColumn: string = 'key';\n\n // Names for the main tables in the database\n public tableNames: { [key: string]: string } = {\n main: 'tableCfgs',\n revision: 'revisions',\n };\n\n /// Suffix handling for the database\n private _suffix: { [key: string]: string } = {\n col: '_col',\n tbl: '_tbl',\n tmp: '_tmp',\n };\n\n // ********************************************************************\n // add and remove suffixes for use in SQL statements\n private _addFix(name: string, fix: string): string {\n return name.endsWith(fix) ? name : name + fix;\n }\n\n public addTableSuffix(name: string): string {\n return this._addFix(name, this._suffix.tbl);\n }\n\n public addColumnSuffix(name: string): string {\n return this._addFix(name, this._suffix.col);\n }\n\n public addTmpSuffix(name: string): string {\n return this._addFix(name, this._suffix.tmp);\n }\n\n private _removeFix(name: string, fix: string): string {\n return name.endsWith(fix) ? name.slice(0, -fix.length) : name;\n }\n\n public removeTableSuffix(name: string): string {\n return this._removeFix(name, this._suffix.tbl);\n }\n\n public removeColumnSuffix(name: string): string {\n return this._removeFix(name, this._suffix.col);\n }\n\n public removeTmpSuffix(name: string): string {\n return this._removeFix(name, this._suffix.tmp);\n }\n}\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { hip } from '@rljson/hash';\nimport {\n iterateTables,\n Rljson,\n TableCfg,\n TableKey,\n TableType,\n throwOnInvalidTableCfg,\n validateRljsonAgainstTableCfg,\n} from '@rljson/rljson';\n\nimport { IoMem } from './io-mem.ts';\nimport { Io } from './io.ts';\n\nexport type IoObserver = (data: Rljson) => void;\n\n/**\n * Provides utility functions for the Io interface.\n */\nexport class IoTools {\n /**\n * Constructor\n * @param io The Io interface to use\n */\n constructor(public readonly io: Io) {}\n\n /**\n * Returns the table configuration of the tableCfgs table.\n */\n static get tableCfgsTableCfg() {\n const tableCfg = hip<TableCfg>({\n _hash: '',\n key: 'tableCfgs',\n type: 'tableCfgs',\n isHead: false,\n isRoot: false,\n isShared: true,\n previous: '',\n\n columns: [\n {\n key: '_hash',\n type: 'string',\n titleShort: 'Hash',\n titleLong: 'Row Hash',\n },\n {\n key: 'key',\n type: 'string',\n titleShort: 'Key',\n titleLong: 'Table Key',\n },\n {\n key: 'type',\n type: 'string',\n titleShort: 'Type',\n titleLong: 'Content Type',\n },\n {\n key: 'isHead',\n type: 'boolean',\n titleShort: 'Is Head',\n titleLong: 'Is Head Table',\n },\n {\n key: 'isRoot',\n type: 'boolean',\n titleShort: 'Is Root',\n titleLong: 'Is Root Table',\n },\n {\n key: 'isShared',\n type: 'boolean',\n titleShort: 'Is Shared',\n titleLong: 'Is Shared Table',\n },\n {\n key: 'previous',\n type: 'string',\n titleShort: 'Previous',\n titleLong: 'Previous Table Configuration Hash',\n },\n {\n key: 'columns',\n type: 'jsonArray',\n titleShort: 'Columns',\n titleLong: 'Column Configurations',\n },\n ],\n });\n\n return tableCfg;\n }\n\n /**\n * Initializes the revisions table.\n */\n initRevisionsTable = async () => {\n const tableCfg: TableCfg = {\n key: 'revisions',\n type: 'revisions',\n isHead: true,\n isRoot: true,\n isShared: false,\n\n columns: [\n {\n key: '_hash',\n type: 'string',\n titleShort: 'Hash',\n titleLong: 'Row Hash',\n },\n {\n key: 'table',\n type: 'string',\n titleShort: 'Table',\n titleLong: 'Table Key',\n },\n {\n key: 'predecessor',\n type: 'string',\n titleShort: 'Predecessor',\n titleLong: 'Predecessor Revision Hash',\n },\n {\n key: 'successor',\n type: 'string',\n titleShort: 'Successor',\n titleLong: 'Successor Revision Hash',\n },\n {\n key: 'timestamp',\n type: 'number',\n titleShort: 'Timestamp',\n titleLong: 'Revision Timestamp',\n },\n {\n key: 'id',\n type: 'string',\n titleShort: 'ID',\n titleLong: 'Revision ID',\n },\n ],\n };\n\n await this.io.createOrExtendTable({ tableCfg });\n };\n\n /**\n * Example object for test purposes\n * @returns An instance of io tools\n */\n static example = async () => {\n const io = await IoMem.example();\n await io.init();\n await io.isReady();\n return new IoTools(io);\n };\n\n /**\n * Throws if the table does not exist\n */\n async throwWhenTableDoesNotExist(table: TableKey): Promise<void> {\n const exists = await this.io.tableExists(table);\n if (!exists) {\n throw new Error(`Table \"${table}\" not found`);\n }\n }\n\n /**\n * Throws if any of the tables in rljson do not exist\n * @param rljson - The Rljson object to check\n */\n async throwWhenTablesDoNotExist(rljson: Rljson): Promise<void> {\n try {\n await iterateTables(rljson, async (tableKey) => {\n const exists = await this.io.tableExists(tableKey);\n if (!exists) {\n throw new Error(`Table \"${tableKey}\" not found`);\n }\n });\n } catch (e) {\n const missingTables = (e as Array<any>).map((e) => e.tableKey);\n\n throw new Error(\n `The following tables do not exist: ${missingTables.join(', ')}`,\n );\n }\n }\n\n /**\n * Returns the current table cfgs of all tables\n * @returns The table configuration of all tables\n */\n async tableCfgs(): Promise<TableCfg[]> {\n const tables = await this.io.rawTableCfgs();\n\n // Take the latest version of each type key\n const newestVersion: Record<TableKey, TableCfg> = {};\n for (let i = tables.length - 1; i >= 0; i--) {\n const table = tables[i];\n const existing = newestVersion[table.key];\n if (!existing || existing.columns.length < table.columns.length) {\n newestVersion[table.key] = table;\n }\n }\n\n // Sort the tables by key\n /* v8 ignore next -- @preserve */\n const resultData = Object.values(newestVersion).sort((a, b) => {\n if (a.key < b.key) {\n return -1;\n }\n if (a.key > b.key) {\n return 1;\n }\n\n return 0;\n });\n return resultData;\n }\n\n /**\n * Returns a list with all table names\n */\n async allTableKeys(): Promise<string[]> {\n const result = (await this.tableCfgs()).map((e) => e.key);\n return result;\n }\n\n /**\n * Returns the configuration of a given table\n */\n async tableCfg(table: TableKey): Promise<TableCfg> {\n const tableCfg = await this.tableCfgOrNull(table);\n if (!tableCfg) {\n throw new Error(`Table \"${table}\" not found`);\n }\n\n return tableCfg!;\n }\n\n /**\n * Returns the configuration of a given table or null if it does not exist.\n\n */\n async tableCfgOrNull(table: TableKey): Promise<TableCfg | null> {\n const tableCfgs = await this.tableCfgs();\n const tableCfg = tableCfgs.find((e) => e.key === table);\n return tableCfg ?? null;\n }\n\n /**\n * Returns a list of all column names of a given table\n */\n async allColumnKeys(table: TableKey): Promise<string[]> {\n const tableCfg = await this.tableCfg(table);\n const result = tableCfg.columns.map((column) => column.key);\n return result;\n }\n\n /**\n * Throws when a column does not exist in a given table\n * @param table - The table to check\n * @param columns - The column to check\n */\n async throwWhenColumnDoesNotExist(\n table: TableKey,\n columns: string[],\n ): Promise<void> {\n const tableCfg = await this.tableCfg(table);\n const columnKeys = tableCfg.columns.map((column) => column.key);\n const missingColumns = columns.filter(\n (column) => !columnKeys.includes(column),\n );\n if (missingColumns.length > 0) {\n throw new Error(\n `The following columns do not exist in table \"${table}\": ${missingColumns.join(\n ', ',\n )}.`,\n );\n }\n }\n\n /**\n * Throws when a table update is not compatible with the current table\n * configuration.\n */\n async throwWhenTableIsNotCompatible(update: TableCfg): Promise<void> {\n const prefix = `Invalid update of table able \"${update.key}\"`;\n\n throwOnInvalidTableCfg(update);\n\n // Check compatibility with existing table\n const existing = await this.tableCfgOrNull(update.key);\n if (existing) {\n // Have columns been deleted?\n if (existing.columns.length > update.columns.length) {\n const deletedColumnKeys = existing.columns\n .map((column) => column.key)\n .filter(\n (key) => !update.columns.some((column) => column.key === key),\n );\n /* v8 ignore next -- @preserve */\n if (deletedColumnKeys.length > 0) {\n const deletedColumns = deletedColumnKeys.join(', ');\n throw new Error(\n `${prefix}: Columns must not be deleted. ` +\n `Deleted columns: ${deletedColumns}}`,\n );\n }\n }\n\n // Have column keys changed?\n for (let i = 0; i < existing.columns.length; i++) {\n const before = existing.columns[i].key;\n const after = update.columns[i].key;\n if (before !== after) {\n throw new Error(\n `${prefix}: ` +\n `Column keys must not change! ` +\n `Column \"${before}\" was renamed into \"${after}\".`,\n );\n }\n }\n\n // Have column types changed?\n for (let i = 0; i < existing.columns.length; i++) {\n const column = existing.columns[i].key;\n const before = existing.columns[i].type;\n const after = update.columns[i].type;\n if (before !== after) {\n throw new Error(\n `${prefix}: ` +\n `Column types must not change! ` +\n `Type of column \"${column}\" was changed from \"${before}\" to ${after}.`,\n );\n }\n }\n }\n }\n\n /**\n * Throws if the data in the table do not match the table configuration\n */\n async throwWhenTableDataDoesNotMatchCfg(data: Rljson) {\n const errors: string[] = [];\n\n await iterateTables(data, async (tableKey) => {\n const tableCfg = await this.tableCfg(tableKey);\n const table = data[tableKey];\n\n // Ignore tableCfgs table\n /* v8 ignore next -- @preserve */\n if (table._type === 'tableCfgs') return;\n\n errors.push(...validateRljsonAgainstTableCfg(table._data, tableCfg));\n });\n\n if (errors.length > 0) {\n throw new Error(\n `Table data does not match the configuration.\\n\\nErrors:\\n${errors\n .map((e) => `- ${e}`)\n .join('\\n')}`,\n );\n }\n }\n\n /**\n * Sorts the data of a table by the hash and updates the table hash in place\n */\n sortTableDataAndUpdateHash(table: TableType): void {\n table._data.sort((a, b) => {\n const hashA = a._hash as string;\n const hashB = b._hash as string;\n /* v8 ignore next -- @preserve */\n if (hashA < hashB) {\n return -1;\n }\n /* v8 ignore next -- @preserve */\n if (hashA > hashB) {\n return 1;\n }\n\n /* v8 ignore next -- @preserve */\n return 0;\n });\n\n table._hash = '';\n hip(table, {\n updateExistingHashes: false,\n throwOnWrongHashes: false,\n });\n }\n}\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { hip, hsh } from '@rljson/hash';\nimport { IsReady } from '@rljson/is-ready';\nimport { copy, equals, JsonValue } from '@rljson/json';\nimport {\n ContentType, iterateTablesSync, Rljson, TableCfg, TableKey, TableType\n} from '@rljson/rljson';\n\nimport { IoTools } from './io-tools.ts';\nimport { Io } from './io.ts';\n\n\n/**\n * In-Memory implementation of the Rljson Io interface.\n */\nexport class IoMem implements Io {\n // ...........................................................................\n // Constructor & example\n\n init(): Promise<void> {\n this._isOpen = true;\n return this._init();\n }\n\n close(): Promise<void> {\n this._isOpen = false;\n return Promise.resolve();\n }\n\n get isOpen(): boolean {\n return this._isOpen;\n }\n\n static example = async () => {\n const io = new IoMem();\n await io.init();\n return io;\n };\n\n // ...........................................................................\n // General\n isReady() {\n return this._isReady.promise;\n }\n\n // ...........................................................................\n // Dump\n\n dump(): Promise<Rljson> {\n return this._dump();\n }\n\n async dumpTable(request: { table: string }): Promise<Rljson> {\n return this._dumpTable(request);\n }\n\n // ...........................................................................\n // Meta Data\n\n async contentType(request: { table: string }): Promise<ContentType> {\n return this._contentType(request);\n }\n\n // ...........................................................................\n // Rows\n\n readRows(request: {\n table: string;\n where: { [column: string]: JsonValue };\n }): Promise<Rljson> {\n return this._readRows(request);\n }\n\n async rowCount(table: string): Promise<number> {\n const tableData = this._mem[table] as TableType;\n if (!tableData) {\n throw new Error(`Table \"${table}\" not found`);\n }\n return Promise.resolve(tableData._data.length);\n }\n\n // ...........................................................................\n // Write\n\n write(request: { data: Rljson }): Promise<void> {\n return this._write(request);\n }\n\n // ...........................................................................\n // Table management\n async tableExists(tableKey: TableKey): Promise<boolean> {\n const table = this._mem[tableKey] as TableType;\n return table ? true : false;\n }\n\n createOrExtendTable(request: { tableCfg: TableCfg }): Promise<void> {\n return this._createOrExtendTable(request);\n }\n\n async rawTableCfgs(): Promise<TableCfg[]> {\n const tables = this._mem.tableCfgs._data as TableCfg[];\n return tables;\n }\n\n // ######################\n // Private\n // ######################\n\n private _ioTools!: IoTools;\n\n private _isReady = new IsReady();\n private _isOpen = false;\n\n private _mem: Rljson = hip({} as Rljson);\n\n // ...........................................................................\n private async _init() {\n this._ioTools = new IoTools(this);\n this._initTableCfgs();\n this._updateGlobalHash();\n await this._ioTools.initRevisionsTable();\n hsh(this._mem);\n\n this._isReady.resolve();\n }\n\n // ...........................................................................\n private _initTableCfgs = () => {\n const tableCfg = IoTools.tableCfgsTableCfg;\n\n this._mem.tableCfgs = hip({\n _type: 'tableCfgs',\n _data: [tableCfg],\n _tableCfg: tableCfg._hash as string,\n });\n };\n\n // ...........................................................................\n private _updateGlobalHash() {\n (this._mem as any)._hash = '';\n hip(this._mem, {\n updateExistingHashes: false,\n });\n }\n\n // ...........................................................................\n private _updateTableHash(tableKey: TableKey) {\n const table = this._mem[tableKey] as TableType;\n table._hash = '';\n hip(table, { updateExistingHashes: false });\n }\n\n // ...........................................................................\n private async _createOrExtendTable(request: {\n tableCfg: TableCfg;\n }): Promise<void> {\n // Make sure that the table config is compatible\n // with an potential existing table\n const tableCfg = request.tableCfg;\n await this._ioTools.throwWhenTableIsNotCompatible(tableCfg);\n\n const { key } = tableCfg;\n\n // Recreate hashes in the case the existing hashes are wrong\n const newConfig = hsh(tableCfg);\n\n // Find an existing table config with the same hash\n const existingConfig = await this._ioTools.tableCfgOrNull(key);\n\n // Write the new config into the database\n if (!existingConfig) {\n this._createTable(newConfig, key);\n } else {\n this._extendTable(existingConfig, newConfig);\n }\n }\n\n // ...........................................................................\n private _createTable(newConfig: TableCfg, tableKey: TableKey) {\n // Write the table config into the database\n newConfig = hsh(newConfig);\n this._mem.tableCfgs._data.push(newConfig);\n this._ioTools.sortTableDataAndUpdateHash(this._mem.tableCfgs);\n\n // Create a table and write it into the database\n const table: TableType = {\n _type: newConfig.type,\n _data: [],\n _tableCfg: newConfig._hash as string,\n };\n\n this._mem[tableKey] ??= hip(table);\n\n // Update hashes\n this._updateTableHash(tableKey);\n this._updateGlobalHash();\n }\n\n // ...........................................................................\n private _extendTable(existingConfig: TableCfg, newConfig: TableCfg) {\n // No columns added? Return.\n if (existingConfig.columns.length === newConfig.columns.length) {\n return;\n }\n\n // Write the new table config into the database\n newConfig = hsh(newConfig);\n this._mem.tableCfgs._data.push(newConfig);\n this._ioTools.sortTableDataAndUpdateHash(this._mem.tableCfgs);\n\n // Update the config of the existing table\n const table = this._mem[newConfig.key] as TableType;\n table._tableCfg = newConfig._hash as string;\n\n // Update the hashes\n this._updateTableHash(newConfig.key);\n this._updateGlobalHash();\n }\n\n // ...........................................................................\n\n private async _dump(): Promise<Rljson> {\n return copy(this._mem);\n }\n\n // ...........................................................................\n private async _dumpTable(request: { table: string }): Promise<Rljson> {\n await this._ioTools.throwWhenTableDoesNotExist(request.table);\n\n const table = this._mem[request.table] as TableType;\n\n return {\n [request.table]: copy(table),\n };\n }\n\n // ...........................................................................\n private async _contentType(request: { table: string }): Promise<ContentType> {\n await this._ioTools.throwWhenTableDoesNotExist(request.table);\n\n return (this._mem[request.table] as TableType)._type;\n }\n\n // ...........................................................................\n private async _write(request: { data: Rljson }): Promise<void> {\n const addedData = hsh(request.data);\n this._removeNullValues(addedData);\n const tables = Object.keys(addedData);\n hsh(addedData);\n\n await this._ioTools.throwWhenTablesDoNotExist(request.data);\n await this._ioTools.throwWhenTableDataDoesNotMatchCfg(request.data);\n\n for (const table of tables) {\n if (table.startsWith('_')) {\n continue;\n }\n\n const oldTable = this._mem[table] as TableType;\n const newTable = addedData[table] as TableType;\n\n // Table exists. Merge data\n for (const item of newTable._data) {\n const hash = item._hash;\n const exists = oldTable._data.find((i) => i._hash === hash);\n if (!exists) {\n oldTable._data.push(item as any);\n }\n }\n\n this._ioTools.sortTableDataAndUpdateHash(oldTable);\n }\n\n // Recalc main hashes\n this._updateGlobalHash();\n }\n\n // ...........................................................................\n private async _readRows(request: {\n table: string;\n where: { [column: string]: JsonValue };\n }): Promise<Rljson> {\n await this._ioTools.throwWhenTableDoesNotExist(request.table);\n await this._ioTools.throwWhenColumnDoesNotExist(\n request.table,\n Object.keys(request.where),\n );\n\n // Read table from data\n const table = this._mem[request.table] as TableType;\n\n // Filter table data\n const tableDataFiltered = table._data.filter((row) => {\n for (const column in request.where) {\n const a = row[column];\n const b = request.where[column];\n if (b === null && a === undefined) {\n return true;\n }\n\n if (!equals(a, b)) {\n return false;\n }\n }\n return true;\n });\n\n // Create an table\n const tableFiltered: TableType = {\n _type: table._type,\n _data: tableDataFiltered,\n };\n\n this._ioTools.sortTableDataAndUpdateHash(tableFiltered);\n\n const result: Rljson = {\n [request.table]: tableFiltered,\n };\n\n return result;\n }\n\n _removeNullValues(rljson: Rljson) {\n iterateTablesSync(rljson, (table) => {\n const data = rljson[table]._data;\n\n for (const row of data) {\n for (const key in row) {\n if (row[key] === null) {\n delete row[key];\n }\n }\n }\n });\n }\n}\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { Io } from './io.ts';\nimport { Socket } from './socket.ts';\n\nexport class PeerSocketMock implements Socket {\n private _listenersMap: Map<string | symbol, Array<(...args: any[]) => void>> =\n new Map();\n\n connected: boolean = false;\n disconnected: boolean = true;\n\n constructor(private _io: Io) {}\n\n // ............................................................................\n /**\n * Removes a specific listener for the specified event.\n * @param eventName - The name of the event.\n * @param listener - The callback function to remove.\n * @returns The PeerSocketMock instance for chaining.\n */\n off(eventName: string | symbol, listener: (...args: any[]) => void): this {\n /* v8 ignore next -- @preserve */\n const listeners = this._listenersMap.get(eventName) || [];\n const index = listeners.indexOf(listener);\n /* v8 ignore else -- @preserve */\n if (index !== -1) {\n listeners.splice(index, 1);\n this._listenersMap.set(eventName, listeners);\n }\n return this;\n }\n\n // ............................................................................\n /**\n * Removes all listeners for the specified event, or all listeners if no event is specified.\n * @param eventName - (Optional) The name of the event.\n * @returns The PeerSocketMock instance for chaining.\n */\n removeAllListeners(eventName?: string | symbol): this {\n if (eventName) {\n this._listenersMap.delete(eventName);\n } else {\n this._listenersMap.clear();\n }\n return this;\n }\n\n // ............................................................................\n /**\n * Registers an event listener for the specified event.\n * @param eventName - The name of the event to listen for.\n * @param listener - The callback function to invoke when the event is emitted.\n * @returns The PeerSocketMock instance for chaining.\n */\n on(eventName: string | symbol, listener: (...args: any[]) => void): this {\n if (!this._listenersMap.has(eventName)) {\n this._listenersMap.set(eventName, []);\n }\n this._listenersMap.get(eventName)!.push(listener);\n return this;\n }\n\n // ...........................................................................\n /**\n * Simulates a connection event.\n *\n * Emits the 'connect' event to all registered listeners.\n */\n connect(): void {\n this.connected = true;\n this.disconnected = false;\n\n const listeners = this._listenersMap.get('connect') || [];\n for (const cb of listeners) {\n cb({});\n }\n }\n\n // ...........................................................................\n /**\n * Simulates a disconnection event.\n *\n * Emits the 'disconnect' event to all registered listeners.\n */\n disconnect(): void {\n this.connected = false;\n this.disconnected = true;\n\n const listeners = this._listenersMap.get('disconnect') || [];\n for (const cb of listeners) {\n cb({});\n }\n }\n\n // ............................................................................\n /**\n * Emits an event, invoking the corresponding method on the Io instance.\n * @param eventName - The name of the event to emit.\n * @param args - The arguments to pass to the event listener.\n * @returns\n */\n emit(eventName: string | symbol, ...args: any[]): boolean {\n const fn = (this._io as any)[eventName] as (...args: any[]) => Promise<any>;\n if (typeof fn !== 'function') {\n throw new Error(`Event ${eventName.toString()} not supported`);\n }\n const cb = args[args.length - 1];\n fn.apply(this._io, args.slice(0, -1))\n .then((result) => {\n cb(result, null);\n })\n .catch((err) => {\n cb(null, err);\n });\n\n return true;\n }\n}\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { JsonValue } from '@rljson/json';\nimport { ContentType, Rljson, TableCfg, TableKey } from '@rljson/rljson';\n\nimport { IoMem } from './io-mem.ts';\nimport { Io } from './io.ts';\nimport { PeerSocketMock } from './peer-socket-mock.ts';\nimport { Socket } from './socket.ts';\n\n\nexport class IoPeer implements Io {\n isOpen: boolean = false;\n\n constructor(private _socket: Socket) {}\n\n // ...........................................................................\n /**\n *\n * Initializes the Peer connection.\n * @returns\n */\n async init(): Promise<void> {\n // Update isOpen on connect/disconnect\n this._socket.on('connect', () => {\n this.isOpen = true;\n });\n this._socket.on('disconnect', () => {\n this.isOpen = false;\n });\n\n // Connect the socket\n this._socket.connect();\n\n // Wait for the socket to connect before returning\n return new Promise<void>((resolve) => {\n /* v8 ignore else -- @preserve */\n if (this._socket.connected) {\n this.isOpen = true;\n resolve();\n } else {\n this._socket.on('connect', () => {\n resolve();\n });\n }\n });\n }\n\n // ...........................................................................\n /**\n * Closes the Peer connection.\n * @returns\n */\n\n async close(): Promise<void> {\n // Disconnect the socket and wait for it to complete\n if (!this._socket.connected) return;\n\n return new Promise<void>((resolve) => {\n this._socket.on('disconnect', () => {\n resolve();\n });\n this._socket.disconnect();\n });\n }\n\n // ...........................................................................\n /**\n * Returns a promise that resolves once the Peer connection is ready.\n * @returns\n */\n async isReady(): Promise<void> {\n if (!!this._socket && this._socket.connected === true) this.isOpen = true;\n else this.isOpen = false;\n\n return !!this.isOpen ? Promise.resolve() : Promise.reject();\n }\n\n // ...........................................................................\n /**\n * Dumps the entire database content.\n * @returns A promise that resolves to the dumped database content.\n */\n async dump(): Promise<Rljson> {\n return new Promise((resolve) => {\n // Request dump, resolve once the data is received (ack)\n this._socket.emit('dump', (data: Rljson) => {\n resolve(data);\n });\n });\n }\n\n // ...........................................................................\n /**\n * Dumps a specific table from the database.\n * @param request An object containing the table name to dump.\n * @returns A promise that resolves to the dumped table data.\n */\n dumpTable(request: { table: string }): Promise<Rljson> {\n return new Promise((resolve, reject) => {\n // Request dumpTable, resolve once the data is received (ack)\n this._socket.emit('dumpTable', request, (data: Rljson, error?: Error) => {\n if (error) reject(error);\n resolve(data);\n });\n });\n }\n\n // ...........................................................................\n /**\n * Gets the content type of a specific table.\n * @param request An object containing the table name to get the content type for.\n * @returns A promise that resolves to the content type of the specified table.\n */\n contentType(request: { table: string }): Promise<ContentType> {\n return new Promise((resolve, reject) => {\n // Request contentType, resolve once the data is received (ack)\n this._socket.emit(\n 'contentType',\n request,\n (data: ContentType, error?: Error) => {\n /* v8 ignore next -- @preserve */\n if (error) reject(error);\n resolve(data);\n },\n );\n });\n }\n\n // ...........................................................................\n /**\n * Checks if a specific table exists in the database.\n * @param tableKey The key of the table to check for existence.\n * @returns A promise that resolves to true if the table exists, false otherwise.\n */\n tableExists(tableKey: TableKey): Promise<boolean> {\n return new Promise((resolve) => {\n // Request tableExists, resolve once the data is received (ack)\n this._socket.emit('tableExists', tableKey, (exists: boolean) => {\n resolve(exists);\n });\n });\n }\n\n // ...........................................................................\n /**\n * Creates or extends a table with the given configuration.\n * @param request An object containing the table configuration.\n * @returns A promise that resolves once the table is created or extended.\n */\n createOrExtendTable(request: { tableCfg: TableCfg }): Promise<void> {\n return new Promise((resolve, reject) => {\n // Request createOrExtendTable, resolve once the data is received (ack)\n this._socket.emit(\n 'createOrExtendTable',\n request,\n (_?: boolean, error?: Error) => {\n if (error) reject(error);\n resolve();\n },\n );\n });\n }\n\n // ...........................................................................\n /**\n * Retrieves the raw table configurations from the database.\n * @returns A promise that resolves to an array of table configurations.\n */\n rawTableCfgs(): Promise<TableCfg[]> {\n return new Promise((resolve) => {\n // Request rawTableCfgs, resolve once the data is received (ack)\n this._socket.emit('rawTableCfgs', (data: TableCfg[]) => {\n resolve(data);\n });\n });\n }\n\n // ...........................................................................\n /**\n * Writes data to the database.\n * @param request An object containing the data to write.\n * @returns A promise that resolves once the data is written.\n */\n write(request: { data: Rljson }): Promise<void> {\n return new Promise((resolve, reject) => {\n // Request write, resolve once the data is received (ack)\n this._socket.emit('write', request, (_?: boolean, error?: Error) => {\n if (error) reject(error);\n resolve();\n });\n });\n }\n\n // ...........................................................................\n /**\n * Reads rows from a specific table that match the given criteria.\n * @param request An object containing the table name and the criteria for selecting rows.\n * @returns A promise that resolves to the selected rows.\n */\n readRows(request: {\n table: string;\n where: { [column: string]: JsonValue | null };\n }): Promise<Rljson> {\n return new Promise((resolve, reject) => {\n // Request readRows, resolve once the data is received (ack)\n this._socket.emit(\n 'readRows',\n request,\n (result?: Rljson, error?: Error) => {\n if (error) reject(error);\n resolve(result!);\n },\n );\n });\n }\n\n // ...........................................................................\n /**\n * Retrieves the number of rows in a specific table.\n * @param table The name of the table to count rows in.\n * @returns A promise that resolves to the number of rows in the specified table.\n */\n rowCount(table: string): Promise<number> {\n return new Promise((resolve, reject) => {\n // Request rowCount, resolve once the data is received (ack)\n this._socket.emit('rowCount', table, (count?: number, error?: Error) => {\n if (error) reject(error);\n resolve(count!);\n });\n });\n }\n\n // ...........................................................................\n static example = async () => {\n const ioMem = await IoMem.example();\n const socket = new PeerSocketMock(ioMem);\n const io = new IoPeer(socket);\n await io.init();\n return io;\n };\n}\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { hip } from '@rljson/hash';\nimport { Json, JsonValue, merge } from '@rljson/json';\nimport { ContentType, Rljson, RljsonTable, TableCfg, TableKey, TableType } from '@rljson/rljson';\n\nimport { IoMem } from './io-mem.ts';\nimport { IoPeer } from './io-peer.ts';\nimport { Io } from './io.ts';\nimport { PeerSocketMock } from './peer-socket-mock.ts';\n\n\n// ...........................................................................\n/**\n * Type representing an Io instance along with its capabilities and priority.\n */\nexport type IoMultiIo = {\n io: Io;\n id?: string;\n priority: number;\n read: boolean;\n write: boolean;\n dump: boolean;\n};\n\n// ...........................................................................\n/**\n * Multi Io implementation that combines multiple underlying Io instances\n * with different capabilities (read, write, dump) and priorities.\n */\nexport class IoMulti implements Io {\n isOpen: boolean = false;\n\n constructor(private _ios: Array<IoMultiIo>) {}\n\n // ...........................................................................\n /**\n *\n * Initializes all underlying Io instances.\n * @returns\n */\n async init(): Promise<void> {\n for (let idx = 0; idx < this._ios.length; idx++) {\n const { io } = this._ios[idx];\n if (io.isOpen === false) {\n throw new Error(\n 'All underlying Io instances must be initialized before initializing IoMulti',\n );\n }\n\n this._ios[idx] = { ...this._ios[idx], id: `io-${idx}` };\n }\n\n this.isOpen = true;\n return Promise.resolve();\n }\n\n // ...........................................................................\n /**\n * Closes all underlying Io instances.\n * @returns\n */\n async close(): Promise<void> {\n await Promise.all(this._ios.map((ioMultiIo) => ioMultiIo.io.close()));\n\n this.isOpen = false;\n\n return Promise.resolve();\n }\n\n // ...........................................................................\n /**\n * Returns a promise that resolves once all underlying Io instances are ready.\n * @returns\n */\n isReady(): Promise<void> {\n return Promise.all(\n this._ios.map((ioMultiIo) => ioMultiIo.io.isReady()),\n ).then(() => Promise.resolve());\n }\n\n // ...........................................................................\n /**\n * Dumps the entire database content by merging dumps from all dumpable underlying Io instances.\n * @returns\n */\n async dump(): Promise<Rljson> {\n /* v8 ignore next -- @preserve */\n if (this.dumpables.length === 0) {\n throw new Error('No dumpable Io available');\n }\n\n const dumps = await Promise.all(\n this.dumpables.map(({ io: dumpable }) => dumpable.dump()),\n );\n\n return merge(...dumps) as Rljson;\n }\n\n // ...........................................................................\n /**\n * Dumps a specific table by merging dumps from all dumpable underlying Io instances that contain the table.\n * @param request An object containing the table name to dump.\n * @returns A promise that resolves to the dumped table data.\n */\n async dumpTable(request: { table: string }): Promise<Rljson> {\n /* v8 ignore next -- @preserve */\n if (this.dumpables.length === 0) {\n throw new Error('No dumpable Io available');\n }\n\n const dumps: Rljson[] = [];\n\n for (const { io: dumpable } of this.dumpables) {\n try {\n const dump = await dumpable.dumpTable(request);\n dumps.push(dump);\n } catch {\n continue; // Table does not exist in this dumpable Io\n }\n }\n\n if (dumps.length === 0) {\n throw new Error(`Table \"${request.table}\" not found`);\n }\n\n return merge(...dumps) as Rljson;\n }\n\n // ...........................................................................\n /**\n * Retrieves the content type of a specific table from the first underlying readable Io instance that contains the table.\n * @param request An object containing the table name.\n * @returns A promise that resolves to the content type of the table.\n */\n async contentType(request: { table: string }): Promise<ContentType> {\n /* v8 ignore next -- @preserve */\n if (this.readables.length === 0) {\n throw new Error('No readable Io available');\n }\n\n for (const { io: readable } of this.readables) {\n return readable.contentType(request);\n }\n /* v8 ignore next -- @preserve */\n throw new Error(`Table \"${request.table}\" not found`);\n }\n\n // ...........................................................................\n /**\n * Checks if a specific table exists in any of the underlying readable Io instances.\n * @param tableKey The key of the table to check.\n * @returns A promise that resolves to true if the table exists in any readable Io, false otherwise.\n */\n async tableExists(tableKey: TableKey): Promise<boolean> {\n /* v8 ignore next -- @preserve */\n if (this.readables.length === 0) {\n throw new Error('No readable Io available');\n }\n\n for (let i = 0; i < this.readables.length; i++) {\n const readable = this.readables[i].io;\n const exists = await readable.tableExists(tableKey);\n if (exists) {\n return true;\n }\n }\n return false;\n }\n\n // ...........................................................................\n /**\n * Creates or extends a table in all underlying writable Io instances.\n * @param request An object containing the table configuration.\n * @returns A promise that resolves once the table has been created or extended in all writable Io instances.\n */\n createOrExtendTable(request: { tableCfg: TableCfg }): Promise<void> {\n /* v8 ignore next -- @preserve */\n if (this.writables.length === 0) {\n throw new Error('No writable Io available');\n }\n //Create or extend table in all writables in parallel and resolve when all have completed\n const creations = this.writables.map(({ io: writable }) =>\n writable.createOrExtendTable(request),\n );\n return Promise.all(creations).then(() => Promise.resolve());\n }\n\n // ...........................................................................\n /**\n * Retrieves the raw table configurations from the highest priority underlying readable Io instance.\n * @returns A promise that resolves to an array of table configurations.\n */\n async rawTableCfgs(): Promise<TableCfg[]> {\n /* v8 ignore next -- @preserve */\n if (this.readables.length === 0) {\n throw new Error('No readable Io available');\n }\n\n const rawTableCfgs: Map<string, TableCfg> = new Map();\n for (const { io: readable } of this.readables) {\n const cfgs = await readable.rawTableCfgs();\n /* v8 ignore else -- @preserve */\n if (cfgs.length > 0) {\n for (const tableCfg of cfgs) {\n if (!rawTableCfgs.has(tableCfg.key)) {\n rawTableCfgs.set(tableCfg.key, tableCfg);\n }\n }\n }\n }\n return Array.from(rawTableCfgs.values());\n }\n\n // ...........................................................................\n /**\n * Writes data to all underlying writable Io instances.\n * @param request - An object containing the data to write.\n * @returns A promise that resolves once the data has been written to all writable Io instances.\n */\n write(request: { data: Rljson }): Promise<void> {\n /* v8 ignore next -- @preserve */\n if (this.writables.length === 0) {\n throw new Error('No writable Io available');\n }\n\n // Write to all writables in parallel and resolve when all have completed\n const writes = this.writables.map(({ io: writable }) =>\n writable.write(request),\n );\n return Promise.all(writes).then(() => Promise.resolve());\n }\n\n // ...........................................................................\n /**\n * Reads rows from a specific table by merging rows from all underlying readable Io instances.\n * @param request An object containing the table name and where clause.\n * @returns A promise that resolves to the read rows.\n */\n async readRows(request: {\n table: string;\n where: { [column: string]: JsonValue | null };\n }): Promise<Rljson> {\n /* v8 ignore next -- @preserve */\n if (this.readables.length === 0) {\n throw new Error('No readable Io available');\n }\n\n let tableExistsAny = false;\n const rows: Map<string, Json> = new Map();\n let type: ContentType | undefined = undefined;\n let readFrom: string = '';\n\n const errors: Error[] = [];\n for (const readable of this.readables) {\n // Read rows from this readable Io\n let tableRows: any[] = [];\n let tableType: ContentType;\n\n try {\n const { [request.table]: tableData } = await readable.io.readRows(\n request,\n );\n tableRows = (tableData as RljsonTable<Json, ContentType>)._data;\n tableType = (tableData as RljsonTable<Json, ContentType>)._type;\n tableExistsAny = true;\n readFrom = readable.id ?? '';\n } catch (e) {\n errors.push(e as Error);\n continue; // Table does not exist in this readable Io\n }\n\n type ??= tableType;\n\n if (tableRows.length === 0) {\n continue; // No rows to merge from this readable Io\n }\n\n /* v8 ignore else -- @preserve */\n for (const tableRow of tableRows) {\n const ref = tableRow._hash;\n rows.set(ref, tableRow);\n }\n\n break; // Stop after the first readable that has the table\n }\n\n if (!tableExistsAny) {\n /* v8 ignore if -- @preserve */\n if (errors.length === 0) {\n throw new Error(`Table \"${request.table}\" not found`);\n } else {\n const preciseErrors = errors.filter(\n (err) => !err.message.includes(`Table \"${request.table}\" not found`),\n );\n if (preciseErrors.length > 0) {\n throw preciseErrors[0];\n } else {\n throw errors[0];\n }\n }\n } else {\n const rljson = {\n [request.table]: hip({ _data: Array.from(rows.values()), _type: type }),\n } as Rljson;\n\n // Write merged rows back to all writables (hot-swapping cache)\n if (this.writables.length > 0 && rows.size > 0) {\n for (const writeable of this.writables) {\n if (writeable.id === readFrom) {\n continue; // Skip writing back to the source readable Io\n }\n /* v8 ignore next -- @preserve */\n try {\n await writeable.io.write({\n data: rljson,\n });\n } catch {\n continue; // Table does not exist in this writable Io\n }\n }\n }\n\n // Return merged rows\n return rljson;\n }\n }\n\n // ...........................................................................\n /**\n * Retrieves the row count of a specific table by aggregating row counts from all dumpable underlying Io instances.\n * @param table The name of the table.\n * @returns A promise that resolves to the row count of the table.\n */\n async rowCount(table: string): Promise<number> {\n /* v8 ignore next -- @preserve */\n if (this.dumpables.length === 0) {\n throw new Error('No dumpable Io available');\n }\n\n const dumpTable = await this.dumpTable({ table });\n const tableData: TableType = dumpTable[table];\n /* v8 ignore next -- @preserve */\n if (!tableData) {\n throw new Error(`Table \"${table}\" not found`);\n }\n return Promise.resolve(tableData._data.length);\n }\n\n // ...........................................................................\n /**\n * Gets the list of underlying readable Io instances, sorted by priority.\n */\n get readables(): Array<IoMultiIo> {\n return this._ios\n .filter((ioMultiIo) => ioMultiIo.read)\n .sort((a, b) => a.priority - b.priority);\n }\n\n // ...........................................................................\n /**\n * Gets the list of underlying writable Io instances, sorted by priority.\n */\n get writables(): Array<IoMultiIo> {\n return this._ios\n .filter((ioMultiIo) => ioMultiIo.write)\n .sort((a, b) => a.priority - b.priority);\n }\n\n // ...........................................................................\n /**\n * Gets the list of underlying dumpable Io instances, sorted by priority.\n */\n get dumpables(): Array<IoMultiIo> {\n return this._ios\n .filter((ioMultiIo) => ioMultiIo.dump)\n .sort((a, b) => a.priority - b.priority);\n }\n\n // ...........................................................................\n static example = async () => {\n const ioPeerMem = await IoMem.example();\n await ioPeerMem.init();\n\n const ioPeerSocket = new PeerSocketMock(ioPeerMem);\n const ioPeer = new IoPeer(ioPeerSocket);\n await ioPeer.init();\n\n const ioMem = await IoMem.example();\n await ioMem.init();\n\n const ios: Array<IoMultiIo> = [\n { io: ioPeer, priority: 1, read: true, write: false, dump: false },\n { io: ioMem, priority: 0, read: true, write: true, dump: true },\n ];\n\n const ioMulti = new IoMulti(ios);\n await ioMulti.init();\n\n return ioMulti;\n };\n}\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { Io } from './io.ts';\nimport { Socket } from './socket.ts';\n\n\n/**\n * Bridges Socket events to Io method calls.\n *\n * This class listens to socket events and translates them into corresponding\n * Io method calls, automatically registering all Io interface methods.\n */\nexport class IoPeerBridge {\n private _eventHandlers: Map<string | symbol, (...args: any[]) => void> =\n new Map();\n\n constructor(private _io: Io, private _socket: Socket) {}\n\n /**\n * Starts the bridge by setting up connection event handlers and\n * automatically registering all Io methods.\n */\n start(): void {\n this._socket.on('connect', () => this._handleConnect());\n this._socket.on('disconnect', () => this._handleDisconnect());\n\n // Automatically register all Io interface methods\n this._registerIoMethods();\n }\n\n /**\n * Stops the bridge by removing all event handlers.\n */\n stop(): void {\n /* v8 ignore next -- @preserve */\n this._socket.off('connect', () => this._handleConnect());\n /* v8 ignore next -- @preserve */\n this._socket.off('disconnect', () => this._handleDisconnect());\n\n for (const [eventName, handler] of this._eventHandlers) {\n this._socket.off(eventName, handler);\n }\n this._eventHandlers.clear();\n }\n\n /**\n * Automatically registers all Io interface methods as socket event handlers.\n */\n private _registerIoMethods(): void {\n // Core Io interface methods\n const ioMethods = [\n 'init',\n 'isReady',\n 'close',\n 'tableExists',\n 'createOrExtendTable',\n 'write',\n 'readRows',\n 'rowCount',\n 'dumpTable',\n 'dump',\n 'contentType',\n 'rawTableCfgs',\n ];\n\n for (const methodName of ioMethods) {\n this.registerEvent(methodName);\n }\n }\n\n /**\n * Registers a socket event to be translated to an Io method call.\n *\n * @param eventName - The socket event name (should match an Io method name)\n * @param ioMethodName - (Optional) The Io method name if different from eventName\n */\n registerEvent(eventName: string, ioMethodName?: string): void {\n const methodName = ioMethodName || eventName;\n\n /* v8 ignore next -- @preserve */\n const handler = (...args: any[]) => {\n // The last argument is expected to be a callback function\n const callback = args[args.length - 1];\n const methodArgs = args.slice(0, -1);\n\n // Get the Io method\n const ioMethod = (this._io as any)[methodName];\n\n /* v8 ignore next -- @preserve */\n if (typeof ioMethod !== 'function') {\n const error = new Error(\n `Method \"${methodName}\" not found on Io instance`,\n );\n if (typeof callback === 'function') {\n callback(null, error);\n }\n return;\n }\n\n // Call the Io method and handle the response\n /* v8 ignore next -- @preserve */\n ioMethod\n .apply(this._io, methodArgs)\n .then((result: any) => {\n if (typeof callback === 'function') {\n // Call callback with just the result (no error parameter when successful)\n callback(result, null); // Two arguments\n }\n })\n .catch((error: any) => {\n if (typeof callback === 'function') {\n // For errors, send null as result and error as second parameter\n callback(null, error); // Two arguments\n }\n });\n };\n\n this._eventHandlers.set(eventName, handler);\n this._socket.on(eventName, handler);\n }\n\n /**\n * Registers multiple socket events at once.\n *\n * @param eventNames - Array of event names to register\n */\n registerEvents(eventNames: string[]): void {\n for (const eventName of eventNames) {\n this.registerEvent(eventName);\n }\n }\n\n /**\n * Unregisters a socket event handler.\n *\n * @param eventName - The event name to unregister\n */\n unregisterEvent(eventName: string | symbol): void {\n const handler = this._eventHandlers.get(eventName);\n if (handler) {\n this._socket.off(eventName, handler);\n this._eventHandlers.delete(eventName);\n }\n }\n\n /**\n * Emits a result back through the socket.\n *\n * @param eventName - The event name to emit\n * @param data - The data to send\n */\n emitToSocket(eventName: string | symbol, ...data: any[]): void {\n this._socket.emit(eventName, ...data);\n }\n\n /**\n * Calls an Io method directly and emits the result through the socket.\n *\n * @param ioMethodName - The Io method to call\n * @param socketEventName - The socket event to emit with the result\n * @param args - Arguments to pass to the Io method\n */\n async callIoAndEmit(\n ioMethodName: string,\n socketEventName: string | symbol,\n ...args: any[]\n ): Promise<void> {\n try {\n const ioMethod = (this._io as any)[ioMethodName];\n\n if (typeof ioMethod !== 'function') {\n throw new Error(`Method \"${ioMethodName}\" not found on Io instance`);\n }\n\n const result = await ioMethod.apply(this._io, args);\n this._socket.emit(socketEventName, result, null);\n } catch (error) {\n this._socket.emit(socketEventName, null, error);\n }\n }\n\n /* v8 ignore next -- @preserve */\n private _handleConnect(): void {\n // Override this method in subclasses to handle connection events\n }\n\n /* v8 ignore next -- @preserve */\n private _handleDisconnect(): void {\n // Override this method in subclasses to handle disconnection events\n }\n\n /**\n * Gets the current socket instance.\n */\n get socket(): Socket {\n return this._socket;\n }\n\n /**\n * Gets the current Io instance.\n */\n get io(): Io {\n return this._io;\n }\n\n /**\n * Returns whether the socket is currently connected.\n */\n get isConnected(): boolean {\n return this._socket.connected;\n }\n}\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { JsonValue } from '@rljson/json';\nimport { Rljson, TableCfg, TableKey } from '@rljson/rljson';\n\nimport { Io } from './io.ts';\nimport { Socket } from './socket.ts';\n\n\nexport class IoServer {\n private _sockets: Socket[] = [];\n\n constructor(private readonly _io: Io) {}\n\n // ...........................................................................\n /**\n * Adds a socket to the IoServer instance.\n * @param socket - The socket to add.\n */\n async addSocket(socket: Socket): Promise<void> {\n // Add transport layer to the socket\n await this._addTransportLayer(socket);\n\n // Add socket to the list of sockets\n this._sockets.push(socket);\n }\n\n // ...........................................................................\n /**\n * Removes a transport layer from the given socket.\n * @param socket - The socket to remove the transport layer from.\n */\n removeSocket(socket: Socket): void {\n this._sockets = this._sockets.filter((s) => s !== socket);\n }\n\n // ...........................................................................\n /**\n * Adds a transport layer to the given socket.\n * @param socket - The socket to add the transport layer to.\n */\n private async _addTransportLayer(socket: Socket): Promise<void> {\n // CRUD operations\n const crud = this._generateTransportLayerCRUD(this._io);\n for (const [key, fn] of Object.entries(crud)) {\n socket.on(key, (...args: any[]) => {\n const cb = args[args.length - 1];\n\n fn.apply(this, args.slice(0, -1))\n .then((result) => {\n cb(result, null);\n })\n .catch((err) => {\n cb(null, err);\n });\n });\n }\n }\n\n // ...........................................................................\n /**\n * Creates or extends a table with the given configuration.\n * @param request - An object containing the table configuration.\n */\n private async createOrExtendTable(request: {\n tableCfg: TableCfg;\n }): Promise<void> {\n return this._io.createOrExtendTable(request);\n }\n\n // ...........................................................................\n /**\n * Generates a transport layer object for the given Io instance.\n * @param io - The Io instance to generate the transport layer for.\n * @returns An object containing methods that correspond to the Io interface.\n */\n private _generateTransportLayerCRUD = (io: Io) =>\n ({\n init: () => io.init(),\n close: () => io.close(),\n isOpen: () =>\n new Promise((resolve) => resolve(io.isOpen)) as Promise<boolean>,\n isReady: () => io.isReady(),\n dump: () => io.dump(),\n dumpTable: (request: { table: string }) => io.dumpTable(request),\n contentType: (request: { table: string }) => io.contentType(request),\n tableExists: (tableKey: TableKey) => io.tableExists(tableKey),\n createOrExtendTable: (request: { tableCfg: TableCfg }) =>\n this.createOrExtendTable(request),\n rawTableCfgs: () => io.rawTableCfgs(),\n write: (request: { data: Rljson }) => io.write(request),\n readRows: (request: {\n table: string;\n where: { [column: string]: JsonValue | null };\n }) => io.readRows(request),\n rowCount: (table: string) => io.rowCount(table),\n } as { [key: string]: (...args: any[]) => Promise<any> });\n}\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { Io, IoMem } from './index.ts';\n\n// .............................................................................\n/**\n * Io implementation need to implement this interface to be used in\n * conformance tests.\n */\nexport interface IoTestSetup {\n /** setup before the single setups */\n beforeAll: () => Promise<void>;\n\n /**\n * Initializes the io implementation.\n * @returns The io implementation.\n */\n beforeEach: () => Promise<void>;\n\n /**\n * Tears down the io implementation.\n * @returns The io implementation.\n */\n afterEach: () => Promise<void>;\n\n /** cleanup after all tests */\n afterAll: () => Promise<void>;\n\n /**\n * The io implementation to be used in the conformance tests.\n */\n io: Io;\n}\n\n// .............................................................................\n// Example implementation of the IoTestSetup interface\nexport const exampleTestSetup = (): IoTestSetup => {\n return {\n io: new IoMem(),\n beforeAll: async () => {\n // This method can be used for any additional setup required before init.\n // Currently, it does nothing.\n },\n\n beforeEach: async () => {\n // Initialize the io implementation\n },\n afterEach: async () => {\n // Tear down the io implementation\n },\n\n afterAll: async () => {\n // This method can be used for any additional cleanup after tearDown.\n },\n };\n};\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { JsonValue } from '@rljson/json';\nimport { ContentType, Rljson, TableCfg, TableKey } from '@rljson/rljson';\n\n\n// .............................................................................\nexport interface Io {\n // ...........................................................................\n // General\n\n /** Starts the initialization */\n init(): Promise<void>;\n\n /** Closes the io */\n close(): Promise<void>;\n\n /** Returns true if io is opened */\n isOpen: boolean;\n\n /** A promise resolving once the Io interface is ready\n *\n * 💡 Use @rljson/is-ready\n */\n isReady(): Promise<void>;\n\n // ...........................................................................\n // Dump\n\n /** Returns the complete db content as Rljson */\n dump(): Promise<Rljson>;\n\n /** Returns the dump of a complete table */\n dumpTable(request: { table: string }): Promise<Rljson>;\n\n // ...........................................................................\n // Meta Data\n contentType(request: { table: string }): Promise<ContentType>;\n\n // ...........................................................................\n // Tables\n\n /**\n * Returns true if the table exists\n */\n tableExists(tableKey: TableKey): Promise<boolean>;\n\n /**\n * Creates a table with a given config.\n * If the table already exists, new columns are added to the existing table.\n * If the table does not exist, it is created with the given config.\n * If the table exists and columns are removed, an error is thrown.\n * If the table exists and the column type is changed, an error is thrown.\n */\n createOrExtendTable(request: { tableCfg: TableCfg }): Promise<void>;\n\n /**\n * Returns a json structure returning current table configurations\n */\n rawTableCfgs(): Promise<TableCfg[]>;\n\n // ...........................................................................\n // Write\n\n /** Writes Rljson data into the database */\n write(request: { data: Rljson }): Promise<void>;\n\n // ...........................................................................\n // Read rows\n\n /** Queries a list of rows */\n readRows(request: {\n table: string;\n where: { [column: string]: JsonValue | null };\n }): Promise<Rljson>;\n\n /** Returns the number of rows in the given table */\n rowCount(table: string): Promise<number>;\n}\n\n// .............................................................................\nexport const exampleIo =\n 'Checkout @rljson/io-mem for an example implementation';\n","/* v8 ignore file -- @preserve */\n// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\nimport { Json } from '@rljson/json';\nimport {\n Buffet,\n Cake,\n iterateTablesSync,\n Layer,\n Ref,\n Rljson,\n TableKey,\n} from '@rljson/rljson';\n\n// .............................................................................\n/**\n * Describes a row that references a child table row\n */\nexport interface ParentRef {\n /**\n * The parent table that references the child table\n */\n [parentTable: TableKey]: {\n /**\n * The parent row that references the child row\n */\n [parentRow: Ref]: {\n /**\n * Details about the reference, e.g. an array index etc.\n */\n details?: Json;\n };\n };\n}\n\n// .............................................................................\n/**\n * Describes the parent table rows referencing a child table row\n */\nexport interface ReverseRefs {\n /**\n * The child table we need the referencing rows for\n */\n [childTable: TableKey]: {\n /**\n * The row hashwe need the referencing rows for\n */\n [childRow: Ref]: ParentRef;\n };\n}\n\n/* v8 ignore start */\n\n// .............................................................................\n/**\n * Calculates the reverse references for a given rljson object\n */\nexport const calcReverseRefs = (rljson: Rljson): ReverseRefs => {\n const result: ReverseRefs = {};\n\n // ......................\n // Prepare data structure\n iterateTablesSync(rljson, (childTableKey, table) => {\n const childTable: { [childRowHash: string]: ParentRef } = {};\n result[childTableKey] = childTable;\n for (const childRow of table._data) {\n childTable[childRow._hash] = {};\n }\n });\n\n // ............................\n // Generate reverse references\n iterateTablesSync(rljson, (parentTableKey, parentTable) => {\n // Iterate all rows of each table\n for (const parentTableRow of parentTable._data) {\n // Find out whe other tables & rows are referenced by this row\n // Write these information intto result\n switch (parentTable._type) {\n case 'components':\n _writeComponentRefs(parentTableKey, parentTableRow, result);\n break;\n\n case 'layers': {\n _writeLayerRefs(parentTableKey, parentTableRow, result);\n break;\n }\n\n case 'sliceIds': {\n // Slice ids do not reference other tables\n break;\n }\n\n case 'cakes': {\n _writeCakeRefs(parentTableKey, parentTableRow, result);\n break;\n }\n\n case 'buffets': {\n _writeBuffetRefs(parentTableKey, parentTableRow, result);\n break;\n }\n }\n }\n });\n\n return result;\n};\n\n/* v8 ignore end */\n\n// .............................................................................\nconst _writeComponentRefs = (\n parentTableName: TableKey,\n parentRow: Json,\n result: ReverseRefs,\n) => {\n const parentRowHash = parentRow._hash as string;\n\n for (const parentColumnName in parentRow) {\n if (parentColumnName.startsWith('_')) {\n continue;\n }\n\n if (!parentColumnName.endsWith('Ref')) {\n continue;\n }\n\n const childTableName = parentColumnName.slice(0, -3);\n const childRowHash = parentRow[parentColumnName] as string;\n\n _write(\n result,\n childTableName,\n childRowHash,\n parentTableName,\n parentRowHash,\n );\n }\n};\n\n// .............................................................................\nconst _writeLayerRefs = (\n parentTableName: TableKey,\n parentRow: Layer,\n result: ReverseRefs,\n) => {\n const childTableName = parentRow.componentsTable;\n const parentRowHash = parentRow._hash as string;\n\n for (const sliceId in parentRow.add) {\n if (sliceId.startsWith('_')) {\n continue;\n }\n\n const sliceHash = parentRow.add[sliceId] as string;\n\n _write(result, childTableName, sliceHash, parentTableName, parentRowHash);\n }\n};\n\n// .............................................................................\nconst _writeCakeRefs = (\n parentTableName: TableKey,\n parentRow: Cake,\n result: ReverseRefs,\n) => {\n const parentRowHash = parentRow._hash as string;\n\n for (const layer in parentRow.layers) {\n const childTableName = layer;\n const childRowHash = parentRow.layers[layer] as string;\n _write(\n result,\n childTableName,\n childRowHash,\n parentTableName,\n parentRowHash,\n );\n }\n};\n\n// .............................................................................\nconst _writeBuffetRefs = (\n parentTableName: TableKey,\n parentRow: Buffet,\n result: ReverseRefs,\n) => {\n const parentRowHash = parentRow._hash as string;\n\n for (const item of parentRow.items) {\n const childTableName = item.table;\n const childRowHash = item.ref;\n _write(\n result,\n childTableName,\n childRowHash,\n parentTableName,\n parentRowHash,\n );\n }\n};\n\n// .............................................................................\nconst _write = (\n result: ReverseRefs,\n childTableName: string,\n childRowHash: string,\n parentTableName: string,\n parentRowHash: string,\n) => {\n const referencesForChildTable = (result[childTableName] ??= {});\n const referencesForChildTableRow = (referencesForChildTable[childRowHash] ??=\n {});\n\n referencesForChildTableRow[parentTableName] ??= {};\n referencesForChildTableRow[parentTableName][parentRowHash] ??= {};\n};\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n/* v8 ignore file -- @preserve */\nimport { Socket } from './socket.ts';\n\nexport class SocketMock implements Socket {\n public connected: boolean = false;\n public disconnected: boolean = true;\n\n private _listeners: Map<string | symbol, Array<(...args: any[]) => void>> =\n new Map();\n private _onceListeners: Map<\n string | symbol,\n Array<(...args: any[]) => void>\n > = new Map();\n\n connect(): void {\n if (!this.connected) {\n this.connected = true;\n this.disconnected = false;\n this.emit('connect');\n }\n }\n\n disconnect(): void {\n if (this.connected) {\n this.connected = false;\n this.disconnected = true;\n this.emit('disconnect');\n }\n }\n\n on(eventName: string | symbol, listener: (...args: any[]) => void): this {\n if (!this._listeners.has(eventName)) {\n this._listeners.set(eventName, []);\n }\n this._listeners.get(eventName)!.push(listener);\n return this;\n }\n\n once(eventName: string | symbol, listener: (...args: any[]) => void): this {\n if (!this._onceListeners.has(eventName)) {\n this._onceListeners.set(eventName, []);\n }\n this._onceListeners.get(eventName)!.push(listener);\n return this;\n }\n\n off(eventName: string | symbol, listener?: (...args: any[]) => void): this {\n if (listener) {\n // Remove specific listener\n const regularListeners = this._listeners.get(eventName);\n if (regularListeners) {\n const index = regularListeners.indexOf(listener);\n if (index > -1) {\n regularListeners.splice(index, 1);\n }\n }\n\n const onceListeners = this._onceListeners.get(eventName);\n if (onceListeners) {\n const index = onceListeners.indexOf(listener);\n if (index > -1) {\n onceListeners.splice(index, 1);\n }\n }\n } else {\n // Remove all listeners for the event\n this._listeners.delete(eventName);\n this._onceListeners.delete(eventName);\n }\n return this;\n }\n\n emit(eventName: string | symbol, ...args: any[]): boolean {\n let hasListeners = false;\n\n // Emit to regular listeners\n const regularListeners = this._listeners.get(eventName);\n if (regularListeners && regularListeners.length > 0) {\n hasListeners = true;\n // Create a copy to avoid issues if listeners are removed during emission\n [...regularListeners].forEach((listener) => {\n try {\n listener(...args);\n } catch (error) {\n // In a real EventEmitter, this would be handled differently\n console.error(\n `Error in listener for event ${String(eventName)}:`,\n error,\n );\n }\n });\n }\n\n // Emit to once listeners and remove them\n const onceListeners = this._onceListeners.get(eventName);\n if (onceListeners && onceListeners.length > 0) {\n hasListeners = true;\n // Create a copy and clear the original array\n const listenersToCall = [...onceListeners];\n this._onceListeners.delete(eventName);\n\n listenersToCall.forEach((listener) => {\n try {\n listener(...args);\n } catch (error) {\n console.error(\n `Error in once listener for event ${String(eventName)}:`,\n error,\n );\n }\n });\n }\n\n return hasListeners;\n }\n\n removeAllListeners(eventName?: string | symbol): this {\n if (eventName !== undefined) {\n this._listeners.delete(eventName);\n this._onceListeners.delete(eventName);\n } else {\n this._listeners.clear();\n this._onceListeners.clear();\n }\n return this;\n }\n\n listenerCount(eventName: string | symbol): number {\n const regularCount = this._listeners.get(eventName)?.length || 0;\n const onceCount = this._onceListeners.get(eventName)?.length || 0;\n return regularCount + onceCount;\n }\n\n listeners(eventName: string | symbol): Array<(...args: any[]) => void> {\n const regularListeners = this._listeners.get(eventName) || [];\n const onceListeners = this._onceListeners.get(eventName) || [];\n return [...regularListeners, ...onceListeners];\n }\n\n eventNames(): Array<string | symbol> {\n const allEvents = new Set([\n ...this._listeners.keys(),\n ...this._onceListeners.keys(),\n ]);\n return Array.from(allEvents);\n }\n\n // Test helper methods\n reset(): void {\n this.connected = false;\n this.disconnected = true;\n this.removeAllListeners();\n }\n\n simulateError(error: Error): void {\n this.emit('error', error);\n }\n\n simulateMessage(message: any): void {\n this.emit('message', message);\n }\n\n // Get internal state for testing\n getListeners(): Map<string | symbol, Array<(...args: any[]) => void>> {\n return new Map(this._listeners);\n }\n\n getOnceListeners(): Map<string | symbol, Array<(...args: any[]) => void>> {\n return new Map(this._onceListeners);\n }\n}\n\n// ...existing code...\n","// @license\n// Copyright (c) 2025 Rljson\n//\n// Use of this source code is governed by terms that can be\n// found in the LICENSE file in the root of this package.\n\n//Interface for a generic Socket, similar to Node.js EventEmitter\n//This is a simplified version and may not cover all features of a full EventEmitter\nexport interface Socket {\n connected: boolean;\n disconnected: boolean;\n connect(): void;\n disconnect(): void;\n on(eventName: string | symbol, listener: (...args: any[]) => void): this;\n emit(eventName: string | symbol, ...args: any[]): boolean | this;\n off(eventName: string | symbol, listener: (...args: any[]) => void): this;\n removeAllListeners(eventName?: string | symbol): this;\n}\n\nexport const socketExample = (): Socket => ({\n connected: false,\n disconnected: true,\n connect() {\n this.connected = true;\n this.disconnected = false;\n this.emit('connect');\n },\n disconnect() {\n this.connected = false;\n this.disconnected = true;\n this.emit('disconnect');\n },\n /* v8 ignore next -- @preserve */\n on() {\n // Implementation of event listener registration\n return this;\n },\n /* v8 ignore next -- @preserve */\n emit() {\n // Implementation of event emission\n return true;\n },\n /* v8 ignore next -- @preserve */\n off() {\n // Implementation of event listener removal\n return this;\n },\n /* v8 ignore next -- @preserve */\n removeAllListeners() {\n // Implementation of removing all listeners\n return this;\n },\n});\n"],"names":["e"],"mappings":"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"}
|
|
@@ -6,6 +6,19 @@ export declare class PeerSocketMock implements Socket {
|
|
|
6
6
|
connected: boolean;
|
|
7
7
|
disconnected: boolean;
|
|
8
8
|
constructor(_io: Io);
|
|
9
|
+
/**
|
|
10
|
+
* Removes a specific listener for the specified event.
|
|
11
|
+
* @param eventName - The name of the event.
|
|
12
|
+
* @param listener - The callback function to remove.
|
|
13
|
+
* @returns The PeerSocketMock instance for chaining.
|
|
14
|
+
*/
|
|
15
|
+
off(eventName: string | symbol, listener: (...args: any[]) => void): this;
|
|
16
|
+
/**
|
|
17
|
+
* Removes all listeners for the specified event, or all listeners if no event is specified.
|
|
18
|
+
* @param eventName - (Optional) The name of the event.
|
|
19
|
+
* @returns The PeerSocketMock instance for chaining.
|
|
20
|
+
*/
|
|
21
|
+
removeAllListeners(eventName?: string | symbol): this;
|
|
9
22
|
/**
|
|
10
23
|
* Registers an event listener for the specified event.
|
|
11
24
|
* @param eventName - The name of the event to listen for.
|
package/dist/socket.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export interface Socket {
|
|
|
4
4
|
connect(): void;
|
|
5
5
|
disconnect(): void;
|
|
6
6
|
on(eventName: string | symbol, listener: (...args: any[]) => void): this;
|
|
7
|
-
emit(eventName: string | symbol, ...args: any[]): boolean;
|
|
7
|
+
emit(eventName: string | symbol, ...args: any[]): boolean | this;
|
|
8
|
+
off(eventName: string | symbol, listener: (...args: any[]) => void): this;
|
|
9
|
+
removeAllListeners(eventName?: string | symbol): this;
|
|
8
10
|
}
|
|
9
11
|
export declare const socketExample: () => Socket;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rljson/io",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.63",
|
|
4
4
|
"description": "Low level interface for reading and writing RLJSON data",
|
|
5
5
|
"homepage": "https://github.com/rljson/io",
|
|
6
6
|
"bugs": "https://github.com/rljson/io/issues",
|
|
@@ -20,24 +20,24 @@
|
|
|
20
20
|
],
|
|
21
21
|
"type": "module",
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@types/node": "^
|
|
24
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
25
|
-
"@typescript-eslint/parser": "^8.
|
|
26
|
-
"@vitest/coverage-v8": "^4.0.
|
|
23
|
+
"@types/node": "^25.0.3",
|
|
24
|
+
"@typescript-eslint/eslint-plugin": "^8.50.1",
|
|
25
|
+
"@typescript-eslint/parser": "^8.50.1",
|
|
26
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
27
27
|
"cross-env": "^10.1.0",
|
|
28
|
-
"eslint": "^9.39.
|
|
28
|
+
"eslint": "^9.39.2",
|
|
29
29
|
"eslint-plugin-jsdoc": "^61.5.0",
|
|
30
30
|
"eslint-plugin-tsdoc": "^0.5.0",
|
|
31
31
|
"globals": "^16.5.0",
|
|
32
32
|
"jsdoc": "^4.0.5",
|
|
33
33
|
"read-pkg": "^10.0.0",
|
|
34
34
|
"typescript": "~5.9.3",
|
|
35
|
-
"typescript-eslint": "^8.
|
|
36
|
-
"vite": "^7.
|
|
35
|
+
"typescript-eslint": "^8.50.1",
|
|
36
|
+
"vite": "^7.3.0",
|
|
37
37
|
"vite-node": "^5.2.0",
|
|
38
38
|
"vite-plugin-dts": "^4.5.4",
|
|
39
|
-
"vite-tsconfig-paths": "^
|
|
40
|
-
"vitest": "^4.0.
|
|
39
|
+
"vite-tsconfig-paths": "^6.0.3",
|
|
40
|
+
"vitest": "^4.0.16",
|
|
41
41
|
"vitest-dom": "^0.1.1"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|