@sqlitecloud/drivers 0.0.56 → 1.0.178
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 +1 -0
- package/lib/drivers/connection-tls.d.ts +1 -1
- package/lib/drivers/connection-tls.js +2 -2
- package/lib/drivers/connection-ws.js +3 -3
- package/lib/drivers/connection.d.ts +11 -1
- package/lib/drivers/connection.js +58 -3
- package/lib/drivers/database.js +3 -3
- package/lib/drivers/types.d.ts +24 -17
- package/lib/drivers/utilities.d.ts +10 -2
- package/lib/drivers/utilities.js +96 -33
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/sqlitecloud.drivers.dev.js +8 -8
- package/lib/sqlitecloud.drivers.js +1 -1
- package/package.json +24 -23
|
@@ -26,7 +26,7 @@ return /******/ (() => { // webpackBootstrap
|
|
|
26
26
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
27
27
|
|
|
28
28
|
"use strict";
|
|
29
|
-
eval("\n/**\n * connection-tls.ts - connection via tls socket and sqlitecloud protocol\n */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudTlsConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst connection_1 = __webpack_require__(/*! ./connection */ \"./lib/drivers/connection.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst protocol_1 = __webpack_require__(/*! ./protocol */ \"./lib/drivers/protocol.js\");\nconst tls = __importStar(__webpack_require__(/*! tls */ \"?4235\"));\n/**\n * Implementation of SQLiteCloudConnection that connects to the database using specific Bun APIs\n * that connect to native sockets or tls sockets and communicates via raw, binary protocol.\n */\nclass SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {\n constructor() {\n super(...arguments);\n // processCommands sets up empty buffers, results callback then send the command to the server via socket.write\n // onData is called when data is received, it will process the data until all data is retrieved for a response\n // when response is complete or there's an error, finish is called to call the results callback set by processCommands...\n // buffer to accumulate incoming data until an whole command is received and can be parsed\n this.buffer = Buffer.alloc(0);\n this.startedOn = new Date();\n }\n /** True if connection is open */\n get connected() {\n return !!this.socket;\n }\n /* Opens a connection with the server and sends the initialization commands. Will throw in case of errors. */\n /* eslint-disable @typescript-eslint/no-unused-vars */\n connectTransport(config, callback) {\n console.assert(!this.connected, 'SQLiteCloudTlsConnection.connect - connection already established');\n if (this.config.verbose) {\n console.debug(`-> connecting ${config === null || config === void 0 ? void 0 : config.host}:${config === null || config === void 0 ? void 0 : config.port}`);\n }\n this.config = config;\n const initializationCommands = (0, utilities_1.getInitializationCommands)(config);\n // connect to plain socket, without encryption, only if insecure parameter specified\n // this option is mainly for testing purposes and is not available on production nodes\n // which would need to connect using tls and proper certificates as per code below\n const connectionOptions = {\n host: config.host,\n port: config.port,\n rejectUnauthorized: false,\n // Server name for the SNI (Server Name Indication) TLS extension.\n // https://r2.nodejs.org/docs/v6.11.4/api/tls.html#tls_class_tls_tlssocket\n servername: config.host\n };\n this.socket = tls.connect(connectionOptions, () => {\n var _a;\n if (this.config.verbose) {\n console.debug(`SQLiteCloudTlsConnection - connected to ${this.config.host}, authorized: ${(_a = this.socket) === null || _a === void 0 ? void 0 : _a.authorized}`);\n }\n this.transportCommands(initializationCommands, error => {\n if (this.config.verbose) {\n console.debug(`SQLiteCloudTlsConnection - initialized connection`);\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, error);\n });\n });\n this.socket.on('data', data => {\n this.processCommandsData(data);\n });\n this.socket.on('error', error => {\n this.close();\n this.processCommandsFinish(new types_1.SQLiteCloudError('Connection error', { errorCode: 'ERR_CONNECTION_ERROR', cause: error }));\n });\n this.socket.on('end', () => {\n this.close();\n if (this.processCallback)\n this.processCommandsFinish(new types_1.SQLiteCloudError('Server ended the connection', { errorCode: 'ERR_CONNECTION_ENDED' }));\n });\n this.socket.on('close', () => {\n this.close();\n this.processCommandsFinish(new types_1.SQLiteCloudError('Connection closed', { errorCode: 'ERR_CONNECTION_CLOSED' }));\n });\n return this;\n }\n /** Will send a command immediately (no queueing), return the rowset/result or throw an error */\n transportCommands(commands, callback) {\n var _a, _b, _c, _d, _e;\n // connection needs to be established?\n if (!this.socket) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Connection not established', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' }));\n return this;\n }\n // reset buffer and rowset chunks, define response callback\n this.buffer = Buffer.alloc(0);\n this.startedOn = new Date();\n this.processCallback = callback;\n this.executingCommands = commands;\n // compose commands following SCPC protocol\n const formattedCommands = (0, protocol_1.formatCommand)(commands);\n if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.verbose) {\n console.debug(`-> ${formattedCommands}`);\n }\n const timeoutMs = (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.timeout) !== null && _c !== void 0 ? _c : 0;\n if (timeoutMs > 0) {\n const timeout = setTimeout(() => {\n var _a;\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Connection timeout out', { errorCode: 'ERR_CONNECTION_TIMEOUT' }));\n (_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy();\n this.socket = undefined;\n }, timeoutMs);\n (_d = this.socket) === null || _d === void 0 ? void 0 : _d.write(formattedCommands, 'utf-8', () => {\n clearTimeout(timeout); // Clear the timeout on successful write\n });\n }\n else {\n (_e = this.socket) === null || _e === void 0 ? void 0 : _e.write(formattedCommands, 'utf-8');\n }\n return this;\n }\n /** Handles data received in response to an outbound command sent by processCommands */\n processCommandsData(data) {\n var _a, _b, _c, _d, _e, _f;\n try {\n // append data to buffer as it arrives\n if (data.length && data.length > 0) {\n this.buffer = Buffer.concat([this.buffer, data]);\n }\n let dataType = (_a = this.buffer) === null || _a === void 0 ? void 0 : _a.subarray(0, 1).toString();\n if ((0, protocol_1.hasCommandLength)(dataType)) {\n const commandLength = (0, protocol_1.parseCommandLength)(this.buffer);\n const hasReceivedEntireCommand = this.buffer.length - this.buffer.indexOf(' ') - 1 >= commandLength ? true : false;\n if (hasReceivedEntireCommand) {\n if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.verbose) {\n let bufferString = this.buffer.toString('utf8');\n if (bufferString.length > 1000) {\n bufferString = bufferString.substring(0, 100) + '...' + bufferString.substring(bufferString.length - 40);\n }\n const elapsedMs = new Date().getTime() - this.startedOn.getTime();\n console.debug(`<- ${bufferString} (${elapsedMs}ms)`);\n }\n // need to decompress this buffer before decoding?\n if (dataType === protocol_1.CMD_COMPRESSED) {\n ;\n ({ buffer: this.buffer, dataType } = (0, protocol_1.decompressBuffer)(this.buffer));\n }\n if (dataType !== protocol_1.CMD_ROWSET_CHUNK) {\n const { data } = (0, protocol_1.popData)(this.buffer);\n (_c = this.processCommandsFinish) === null || _c === void 0 ? void 0 : _c.call(this, null, data);\n }\n else {\n // check if rowset received the ending chunk in which case it can be unpacked\n if ((0, protocol_1.bufferEndsWith)(this.buffer, protocol_1.ROWSET_CHUNKS_END)) {\n const parsedData = (0, protocol_1.parseRowsetChunks)([this.buffer]);\n (_d = this.processCommandsFinish) === null || _d === void 0 ? void 0 : _d.call(this, null, parsedData);\n }\n }\n }\n }\n else {\n // command with no explicit len so make sure that the final character is a space\n const lastChar = this.buffer.subarray(this.buffer.length - 1, this.buffer.length).toString('utf8');\n if (lastChar == ' ') {\n const { data } = (0, protocol_1.popData)(this.buffer);\n (_e = this.processCommandsFinish) === null || _e === void 0 ? void 0 : _e.call(this, null, data);\n }\n }\n }\n catch (error) {\n console.assert(error instanceof Error);\n if (error instanceof Error) {\n (_f = this.processCommandsFinish) === null || _f === void 0 ? void 0 : _f.call(this, error);\n }\n }\n }\n /** Completes a transaction initiated by processCommands */\n processCommandsFinish(error, result) {\n if (error) {\n if (this.processCallback) {\n console.error('processCommandsFinish - error', error);\n }\n else {\n console.warn('processCommandsFinish - error with no registered callback', error);\n }\n }\n if (this.processCallback) {\n this.processCallback(error, result);\n // this.processCallback = undefined\n }\n }\n /** Disconnect immediately, release connection, no events. */\n close() {\n if (this.socket) {\n this.socket.removeAllListeners();\n this.socket.destroy();\n this.socket = undefined;\n }\n this.operations.clear();\n return this;\n }\n}\nexports.SQLiteCloudTlsConnection = SQLiteCloudTlsConnection;\nexports[\"default\"] = SQLiteCloudTlsConnection;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/connection-tls.js?");
|
|
29
|
+
eval("\n/**\n * connection-tls.ts - connection via tls socket and sqlitecloud protocol\n */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudTlsConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst connection_1 = __webpack_require__(/*! ./connection */ \"./lib/drivers/connection.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst protocol_1 = __webpack_require__(/*! ./protocol */ \"./lib/drivers/protocol.js\");\nconst tls = __importStar(__webpack_require__(/*! tls */ \"?4235\"));\n/**\n * Implementation of SQLiteCloudConnection that connects to the database using specific tls APIs\n * that connect to native sockets or tls sockets and communicates via raw, binary protocol.\n */\nclass SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {\n constructor() {\n super(...arguments);\n // processCommands sets up empty buffers, results callback then send the command to the server via socket.write\n // onData is called when data is received, it will process the data until all data is retrieved for a response\n // when response is complete or there's an error, finish is called to call the results callback set by processCommands...\n // buffer to accumulate incoming data until an whole command is received and can be parsed\n this.buffer = Buffer.alloc(0);\n this.startedOn = new Date();\n }\n /** True if connection is open */\n get connected() {\n return !!this.socket;\n }\n /* Opens a connection with the server and sends the initialization commands. Will throw in case of errors. */\n /* eslint-disable @typescript-eslint/no-unused-vars */\n connectTransport(config, callback) {\n console.assert(!this.connected, 'SQLiteCloudTlsConnection.connect - connection already established');\n if (this.config.verbose) {\n console.debug(`-> connecting ${config === null || config === void 0 ? void 0 : config.host}:${config === null || config === void 0 ? void 0 : config.port}`);\n }\n this.config = config;\n const initializationCommands = (0, utilities_1.getInitializationCommands)(config);\n // connect to plain socket, without encryption, only if insecure parameter specified\n // this option is mainly for testing purposes and is not available on production nodes\n // which would need to connect using tls and proper certificates as per code below\n const connectionOptions = {\n host: config.host,\n port: config.port,\n rejectUnauthorized: config.host != 'localhost',\n // Server name for the SNI (Server Name Indication) TLS extension.\n // https://r2.nodejs.org/docs/v6.11.4/api/tls.html#tls_class_tls_tlssocket\n servername: config.host\n };\n this.socket = tls.connect(connectionOptions, () => {\n var _a;\n if (this.config.verbose) {\n console.debug(`SQLiteCloudTlsConnection - connected to ${this.config.host}, authorized: ${(_a = this.socket) === null || _a === void 0 ? void 0 : _a.authorized}`);\n }\n this.transportCommands(initializationCommands, error => {\n if (this.config.verbose) {\n console.debug(`SQLiteCloudTlsConnection - initialized connection`);\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, error);\n });\n });\n this.socket.on('data', data => {\n this.processCommandsData(data);\n });\n this.socket.on('error', error => {\n this.close();\n this.processCommandsFinish(new types_1.SQLiteCloudError('Connection error', { errorCode: 'ERR_CONNECTION_ERROR', cause: error }));\n });\n this.socket.on('end', () => {\n this.close();\n if (this.processCallback)\n this.processCommandsFinish(new types_1.SQLiteCloudError('Server ended the connection', { errorCode: 'ERR_CONNECTION_ENDED' }));\n });\n this.socket.on('close', () => {\n this.close();\n this.processCommandsFinish(new types_1.SQLiteCloudError('Connection closed', { errorCode: 'ERR_CONNECTION_CLOSED' }));\n });\n return this;\n }\n /** Will send a command immediately (no queueing), return the rowset/result or throw an error */\n transportCommands(commands, callback) {\n var _a, _b, _c, _d, _e;\n // connection needs to be established?\n if (!this.socket) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Connection not established', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' }));\n return this;\n }\n // reset buffer and rowset chunks, define response callback\n this.buffer = Buffer.alloc(0);\n this.startedOn = new Date();\n this.processCallback = callback;\n this.executingCommands = commands;\n // compose commands following SCPC protocol\n const formattedCommands = (0, protocol_1.formatCommand)(commands);\n if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.verbose) {\n console.debug(`-> ${formattedCommands}`);\n }\n const timeoutMs = (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.timeout) !== null && _c !== void 0 ? _c : 0;\n if (timeoutMs > 0) {\n const timeout = setTimeout(() => {\n var _a;\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Connection timeout out', { errorCode: 'ERR_CONNECTION_TIMEOUT' }));\n (_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy();\n this.socket = undefined;\n }, timeoutMs);\n (_d = this.socket) === null || _d === void 0 ? void 0 : _d.write(formattedCommands, 'utf-8', () => {\n clearTimeout(timeout); // Clear the timeout on successful write\n });\n }\n else {\n (_e = this.socket) === null || _e === void 0 ? void 0 : _e.write(formattedCommands, 'utf-8');\n }\n return this;\n }\n /** Handles data received in response to an outbound command sent by processCommands */\n processCommandsData(data) {\n var _a, _b, _c, _d, _e, _f;\n try {\n // append data to buffer as it arrives\n if (data.length && data.length > 0) {\n this.buffer = Buffer.concat([this.buffer, data]);\n }\n let dataType = (_a = this.buffer) === null || _a === void 0 ? void 0 : _a.subarray(0, 1).toString();\n if ((0, protocol_1.hasCommandLength)(dataType)) {\n const commandLength = (0, protocol_1.parseCommandLength)(this.buffer);\n const hasReceivedEntireCommand = this.buffer.length - this.buffer.indexOf(' ') - 1 >= commandLength ? true : false;\n if (hasReceivedEntireCommand) {\n if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.verbose) {\n let bufferString = this.buffer.toString('utf8');\n if (bufferString.length > 1000) {\n bufferString = bufferString.substring(0, 100) + '...' + bufferString.substring(bufferString.length - 40);\n }\n const elapsedMs = new Date().getTime() - this.startedOn.getTime();\n console.debug(`<- ${bufferString} (${elapsedMs}ms)`);\n }\n // need to decompress this buffer before decoding?\n if (dataType === protocol_1.CMD_COMPRESSED) {\n ;\n ({ buffer: this.buffer, dataType } = (0, protocol_1.decompressBuffer)(this.buffer));\n }\n if (dataType !== protocol_1.CMD_ROWSET_CHUNK) {\n const { data } = (0, protocol_1.popData)(this.buffer);\n (_c = this.processCommandsFinish) === null || _c === void 0 ? void 0 : _c.call(this, null, data);\n }\n else {\n // check if rowset received the ending chunk in which case it can be unpacked\n if ((0, protocol_1.bufferEndsWith)(this.buffer, protocol_1.ROWSET_CHUNKS_END)) {\n const parsedData = (0, protocol_1.parseRowsetChunks)([this.buffer]);\n (_d = this.processCommandsFinish) === null || _d === void 0 ? void 0 : _d.call(this, null, parsedData);\n }\n }\n }\n }\n else {\n // command with no explicit len so make sure that the final character is a space\n const lastChar = this.buffer.subarray(this.buffer.length - 1, this.buffer.length).toString('utf8');\n if (lastChar == ' ') {\n const { data } = (0, protocol_1.popData)(this.buffer);\n (_e = this.processCommandsFinish) === null || _e === void 0 ? void 0 : _e.call(this, null, data);\n }\n }\n }\n catch (error) {\n console.assert(error instanceof Error);\n if (error instanceof Error) {\n (_f = this.processCommandsFinish) === null || _f === void 0 ? void 0 : _f.call(this, error);\n }\n }\n }\n /** Completes a transaction initiated by processCommands */\n processCommandsFinish(error, result) {\n if (error) {\n if (this.processCallback) {\n console.error('processCommandsFinish - error', error);\n }\n else {\n console.warn('processCommandsFinish - error with no registered callback', error);\n }\n }\n if (this.processCallback) {\n this.processCallback(error, result);\n // this.processCallback = undefined\n }\n }\n /** Disconnect immediately, release connection, no events. */\n close() {\n if (this.socket) {\n this.socket.removeAllListeners();\n this.socket.destroy();\n this.socket = undefined;\n }\n this.operations.clear();\n return this;\n }\n}\nexports.SQLiteCloudTlsConnection = SQLiteCloudTlsConnection;\nexports[\"default\"] = SQLiteCloudTlsConnection;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/connection-tls.js?");
|
|
30
30
|
|
|
31
31
|
/***/ }),
|
|
32
32
|
|
|
@@ -37,7 +37,7 @@ eval("\n/**\n * connection-tls.ts - connection via tls socket and sqlitecloud pr
|
|
|
37
37
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
38
38
|
|
|
39
39
|
"use strict";
|
|
40
|
-
eval("\n/**\n * transport-ws.ts - handles low level communication with sqlitecloud server via socket.io websocket\n */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudWebsocketConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst connection_1 = __webpack_require__(/*! ./connection */ \"./lib/drivers/connection.js\");\nconst socket_io_client_1 = __webpack_require__(/*! socket.io-client */ \"./node_modules/socket.io-client/build/cjs/index.js\");\n/**\n * Implementation of TransportConnection that connects to the database indirectly\n * via SQLite Cloud Gateway, a socket.io based deamon that responds to sql query\n * requests by returning results and rowsets in json format. The gateway handles\n * connect, disconnect, retries, order of operations, timeouts, etc.\n */\nclass SQLiteCloudWebsocketConnection extends connection_1.SQLiteCloudConnection {\n /** True if connection is open */\n get connected() {\n return !!this.socket;\n }\n /* Opens a connection with the server and sends the initialization commands. Will throw in case of errors. */\n connectTransport(config, callback) {\n var _a;\n try {\n // connection established while we were waiting in line?\n console.assert(!this.connected, 'Connection already established');\n if (!this.socket) {\n this.config = config;\n const
|
|
40
|
+
eval("\n/**\n * transport-ws.ts - handles low level communication with sqlitecloud server via socket.io websocket\n */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudWebsocketConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst connection_1 = __webpack_require__(/*! ./connection */ \"./lib/drivers/connection.js\");\nconst socket_io_client_1 = __webpack_require__(/*! socket.io-client */ \"./node_modules/socket.io-client/build/cjs/index.js\");\n/**\n * Implementation of TransportConnection that connects to the database indirectly\n * via SQLite Cloud Gateway, a socket.io based deamon that responds to sql query\n * requests by returning results and rowsets in json format. The gateway handles\n * connect, disconnect, retries, order of operations, timeouts, etc.\n */\nclass SQLiteCloudWebsocketConnection extends connection_1.SQLiteCloudConnection {\n /** True if connection is open */\n get connected() {\n return !!this.socket;\n }\n /* Opens a connection with the server and sends the initialization commands. Will throw in case of errors. */\n connectTransport(config, callback) {\n var _a;\n try {\n // connection established while we were waiting in line?\n console.assert(!this.connected, 'Connection already established');\n if (!this.socket) {\n this.config = config;\n const connectionstring = this.config.connectionstring;\n const gatewayUrl = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.gatewayurl) || `${this.config.host === 'localhost' ? 'ws' : 'wss'}://${this.config.host}:4000`;\n this.socket = (0, socket_io_client_1.io)(gatewayUrl, { auth: { token: connectionstring } });\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n catch (error) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, error);\n }\n return this;\n }\n /** Will send a command immediately (no queueing), return the rowset/result or throw an error */\n transportCommands(commands, callback) {\n // connection needs to be established?\n if (!this.socket) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Connection not established', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' }));\n return this;\n }\n this.socket.emit('v1/sql', { sql: commands, row: 'array' }, (response) => {\n if (response === null || response === void 0 ? void 0 : response.error) {\n const error = new types_1.SQLiteCloudError(response.error.detail, Object.assign({}, response.error));\n callback === null || callback === void 0 ? void 0 : callback.call(this, error);\n }\n else {\n const { data, metadata } = response;\n if (data && metadata) {\n if (metadata.numberOfRows !== undefined && metadata.numberOfColumns !== undefined && metadata.columns !== undefined) {\n console.assert(Array.isArray(data), 'SQLiteCloudWebsocketConnection.transportCommands - data is not an array');\n // we can recreate a SQLiteCloudRowset from the response which we know to be an array of arrays\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n const rowset = new rowset_1.SQLiteCloudRowset(metadata, data.flat());\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, rowset);\n return;\n }\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, response === null || response === void 0 ? void 0 : response.data);\n }\n });\n return this;\n }\n /** Disconnect socket.io from server */\n close() {\n var _a;\n console.assert(this.socket !== null, 'SQLiteCloudWebsocketConnection.close - connection already closed');\n if (this.socket) {\n (_a = this.socket) === null || _a === void 0 ? void 0 : _a.close();\n this.socket = undefined;\n }\n this.operations.clear();\n this.socket = undefined;\n return this;\n }\n}\nexports.SQLiteCloudWebsocketConnection = SQLiteCloudWebsocketConnection;\nexports[\"default\"] = SQLiteCloudWebsocketConnection;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/connection-ws.js?");
|
|
41
41
|
|
|
42
42
|
/***/ }),
|
|
43
43
|
|
|
@@ -45,10 +45,10 @@ eval("\n/**\n * transport-ws.ts - handles low level communication with sqliteclo
|
|
|
45
45
|
/*!***********************************!*\
|
|
46
46
|
!*** ./lib/drivers/connection.js ***!
|
|
47
47
|
\***********************************/
|
|
48
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__)
|
|
48
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
49
49
|
|
|
50
50
|
"use strict";
|
|
51
|
-
eval("\n/**\n * connection.ts - base abstract class for sqlitecloud server connections\n */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst queue_1 = __webpack_require__(/*! ./queue */ \"./lib/drivers/queue.js\");\nconst utilities_2 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\n/**\n * Base class for SQLiteCloudConnection handles basics and defines methods.\n * Actual connection management and communication with the server in concrete classes.\n */\nclass SQLiteCloudConnection {\n /** Parse and validate provided
|
|
51
|
+
eval("\n/**\n * connection.ts - base abstract class for sqlitecloud server connections\n */\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst queue_1 = __webpack_require__(/*! ./queue */ \"./lib/drivers/queue.js\");\nconst utilities_2 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\n/**\n * Base class for SQLiteCloudConnection handles basics and defines methods.\n * Actual connection management and communication with the server in concrete classes.\n */\nclass SQLiteCloudConnection {\n /** Parse and validate provided connectionstring or configuration */\n constructor(config, callback) {\n /** Operations are serialized by waiting an any pending promises */\n this.operations = new queue_1.OperationsQueue();\n if (typeof config === 'string') {\n this.config = (0, utilities_1.validateConfiguration)({ connectionstring: config });\n }\n else {\n this.config = (0, utilities_1.validateConfiguration)(config);\n }\n // connect transport layer to server\n this.connect(callback);\n }\n /** Returns the connection's configuration */\n getConfig() {\n return Object.assign({}, this.config);\n }\n //\n // internal methods (some are implemented in concrete classes using different transport layers)\n //\n /** Connect will establish a tls or websocket transport to the server based on configuration and environment */\n connect(callback) {\n this.operations.enqueue(done => {\n this.connectTransport(this.config, error => {\n if (error) {\n console.error(`SQLiteCloudConnection.connect - error connecting ${this.config.host}:${this.config.port} ${error.toString()}`, error);\n this.close();\n }\n if (callback) {\n callback.call(this, error || null);\n }\n done(error);\n });\n });\n return this;\n }\n /** Will log to console if verbose mode is enabled */\n log(message, ...optionalParams) {\n if (this.config.verbose) {\n message = (0, utilities_2.anonimizeCommand)(message);\n console.log(`${new Date().toISOString()} ${this.config.clientid}: ${message}`, ...optionalParams);\n }\n }\n /** Enable verbose logging for debug purposes */\n verbose() {\n this.config.verbose = true;\n }\n /** Will enquee a command to be executed and callback with the resulting rowset/result/error */\n sendCommands(commands, callback) {\n this.operations.enqueue(done => {\n if (!this.connected) {\n const error = new types_1.SQLiteCloudError('Connection not established', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' });\n callback === null || callback === void 0 ? void 0 : callback.call(this, error);\n done(error);\n }\n else {\n this.transportCommands(commands, (error, result) => {\n callback === null || callback === void 0 ? void 0 : callback.call(this, error, result);\n done(error);\n });\n }\n });\n return this;\n }\n /**\n * Sql is a promise based API for executing SQL statements. You can\n * pass a simple string with a SQL statement or a template string\n * using backticks and parameters in ${parameter} format. These parameters\n * will be properly escaped and quoted like when using a prepared statement.\n * @param sql A sql string or a template string in `backticks` format\n * @returns An array of rows in case of selections or an object with\n * metadata in case of insert, update, delete.\n */\n sql(sql, ...values) {\n return __awaiter(this, void 0, void 0, function* () {\n let preparedSql = '';\n // sql is a TemplateStringsArray, the 'raw' property is specific to TemplateStringsArray\n if (Array.isArray(sql) && 'raw' in sql) {\n sql.forEach((string, i) => {\n preparedSql += string + (i < values.length ? '?' : '');\n });\n preparedSql = (0, utilities_1.prepareSql)(preparedSql, ...values);\n }\n else {\n if (typeof sql === 'string') {\n if ((values === null || values === void 0 ? void 0 : values.length) > 0) {\n preparedSql = (0, utilities_1.prepareSql)(sql, ...values);\n }\n else {\n preparedSql = sql;\n }\n }\n else {\n throw new Error('Invalid sql');\n }\n }\n return new Promise((resolve, reject) => {\n this.sendCommands(preparedSql, (error, results) => {\n if (error) {\n reject(error);\n }\n else {\n // metadata for operations like insert, update, delete?\n const context = (0, utilities_2.getUpdateResults)(results);\n resolve(context ? context : results);\n }\n });\n });\n });\n }\n}\nexports.SQLiteCloudConnection = SQLiteCloudConnection;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/connection.js?");
|
|
52
52
|
|
|
53
53
|
/***/ }),
|
|
54
54
|
|
|
@@ -59,7 +59,7 @@ eval("\n/**\n * connection.ts - base abstract class for sqlitecloud server conne
|
|
|
59
59
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
60
60
|
|
|
61
61
|
"use strict";
|
|
62
|
-
eval("\n//\n// database.ts - database driver api, implements and extends sqlite3\n//\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Database = void 0;\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst statement_1 = __webpack_require__(/*! ./statement */ \"./lib/drivers/statement.js\");\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst utilities_2 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\n// Uses eventemitter3 instead of node events for browser compatibility\n// https://github.com/primus/eventemitter3\n/**\n * Creating a Database object automatically opens a connection to the SQLite database.\n * When the connection is established the Database object emits an open event and calls\n * the optional provided callback. If the connection cannot be established an error event\n * will be emitted and the optional callback is called with the error information.\n */\nclass Database extends eventemitter3_1.default {\n constructor(config, mode, callback) {\n super();\n /** Database connections */\n this.connections = [];\n this.config = typeof config === 'string' ? { connectionString: config } : config;\n // mode is optional and so is callback\n // https://github.com/TryGhost/node-sqlite3/wiki/API#new-sqlite3databasefilename--mode--callback\n if (typeof mode === 'function') {\n callback = mode;\n mode = undefined;\n }\n // mode is ignored for now\n // opens first connection to the database automatically\n this.getConnection((error, _connection) => {\n if (callback) {\n callback.call(this, error);\n }\n });\n }\n //\n // private methods\n //\n /** Returns first available connection from connection pool */\n getConnection(callback) {\n var _a, _b, _c;\n // TODO sqlitecloud-js / implement database connection pool #10\n if (((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n }\n else {\n // connect using websocket if tls is not supported or if explicitly requested\n const useWebsocket = utilities_2.isBrowser || ((_b = this.config) === null || _b === void 0 ? void 0 : _b.useWebsocket) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.gatewayUrl);\n if (useWebsocket) {\n // socket.io transport works in both node.js and browser environments and connects via SQLite Cloud Gateway\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-ws */ \"./lib/drivers/connection-ws.js\"))).then(module => {\n this.connections.push(new module.default(this.config, error => {\n if (error) {\n this.handleError(this.connections[0], error, callback);\n }\n else {\n console.assert;\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n this.emitEvent('open');\n }\n }));\n })\n .catch(error => {\n this.handleError(null, error, callback);\n });\n }\n else {\n // tls sockets work only in node.js environments\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-tls */ \"./lib/drivers/connection-tls.js\"))).then(module => {\n this.connections.push(new module.default(this.config, error => {\n if (error) {\n this.handleError(this.connections[0], error, callback);\n }\n else {\n console.assert;\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n this.emitEvent('open');\n }\n }));\n })\n .catch(error => {\n this.handleError(null, error, callback);\n });\n }\n }\n }\n /** Handles an error by closing the connection, calling the callback and/or emitting an error event */\n handleError(connection, error, callback) {\n // an errored connection is thrown out\n if (connection) {\n this.connections = this.connections.filter(c => c !== connection);\n connection.close();\n }\n if (callback) {\n callback.call(this, error);\n }\n else {\n this.emitEvent('error', error);\n }\n }\n /**\n * Some queries like inserts or updates processed via run or exec may generate\n * an empty result (eg. no data was selected), but still have some metadata.\n * For example the server may pass the id of the last row that was modified.\n * In this case the callback results should be empty but the context may contain\n * additional information like lastID, etc.\n * @see https://github.com/TryGhost/node-sqlite3/wiki/API#runsql--param---callback\n * @param results Results received from the server\n * @returns A context object if one makes sense, otherwise undefined\n */\n processContext(results) {\n if (results) {\n if (Array.isArray(results) && results.length > 0) {\n switch (results[0]) {\n case types_1.SQLiteCloudArrayType.ARRAY_TYPE_SQLITE_EXEC:\n return {\n lastID: results[2],\n changes: results[3],\n totalChanges: results[4],\n finalized: results[5] // FINALIZED\n };\n }\n }\n }\n return undefined;\n }\n /** Emits given event with optional arguments on the next tick so callbacks can complete first */\n emitEvent(event, ...args) {\n setTimeout(() => {\n this.emit(event, ...args);\n }, 0);\n }\n //\n // public methods\n //\n /**\n * Returns the configuration with which this database was opened.\n * The configuration is readonly and cannot be changed as there may\n * be multiple connections using the same configuration.\n * @returns {SQLiteCloudConfig} A configuration object\n */\n getConfiguration() {\n return JSON.parse(JSON.stringify(this.config));\n }\n /** Enable verbose mode */\n verbose() {\n this.config.verbose = true;\n for (const connection of this.connections) {\n connection.verbose();\n }\n return this;\n }\n /** Set a configuration option for the database */\n configure(_option, _value) {\n // https://github.com/TryGhost/node-sqlite3/wiki/API#configureoption-value\n return this;\n }\n run(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n // context may include id of last row inserted, total changes, etc...\n const context = this.processContext(results);\n callback === null || callback === void 0 ? void 0 : callback.call(context || this, null, context ? undefined : results);\n }\n });\n }\n });\n return this;\n }\n get(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (results && results instanceof rowset_1.SQLiteCloudRowset && results.length > 0) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, results[0]);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n }\n });\n }\n });\n return this;\n }\n all(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (results && results instanceof rowset_1.SQLiteCloudRowset) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, results);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n }\n });\n }\n });\n return this;\n }\n each(sql, ...params) {\n // extract optional parameters and one or two callbacks\n const { args, callback, complete } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, rowset) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (rowset && rowset instanceof rowset_1.SQLiteCloudRowset) {\n if (callback) {\n for (const row of rowset) {\n callback.call(this, null, row);\n }\n }\n if (complete) {\n ;\n complete.call(this, null, rowset.numberOfRows);\n }\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Invalid rowset'));\n }\n }\n });\n }\n });\n return this;\n }\n /**\n * Prepares the SQL statement and optionally binds the specified parameters and\n * calls the callback when done. The function returns a Statement object.\n * When preparing was successful, the first and only argument to the callback\n * is null, otherwise it is the error object. When bind parameters are supplied,\n * they are bound to the prepared statement before calling the callback.\n */\n prepare(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n return new statement_1.Statement(this, sql, ...args, callback);\n }\n /**\n * Runs all SQL queries in the supplied string. No result rows are retrieved.\n * The function returns the Database object to allow for function chaining.\n * If a query fails, no subsequent statements will be executed (wrap it in a\n * transaction if you want all or none to be executed). When all statements\n * have been executed successfully, or when an error occurs, the callback\n * function is called, with the first parameter being either null or an error\n * object. When no callback is provided and an error occurs, an error event\n * will be emitted on the database object.\n */\n exec(sql, callback) {\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(sql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n const context = this.processContext(results);\n callback === null || callback === void 0 ? void 0 : callback.call(context ? context : this, null);\n }\n });\n }\n });\n return this;\n }\n /**\n * If the optional callback is provided, this function will be called when the\n * database was closed successfully or when an error occurred. The first argument\n * is an error object. When it is null, closing succeeded. If no callback is provided\n * and an error occurred, an error event with the error object as the only parameter\n * will be emitted on the database object. If closing succeeded, a close event with no\n * parameters is emitted, regardless of whether a callback was provided or not.\n */\n close(callback) {\n var _a;\n if (((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0) {\n for (const connection of this.connections) {\n connection.close();\n }\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n this.emitEvent('close');\n }\n /**\n * Loads a compiled SQLite extension into the database connection object.\n * @param path Filename of the extension to load.\n * @param callback If provided, this function will be called when the extension\n * was loaded successfully or when an error occurred. The first argument is an\n * error object. When it is null, loading succeeded. If no callback is provided\n * and an error occurred, an error event with the error object as the only parameter\n * will be emitted on the database object.\n */\n loadExtension(_path, callback) {\n // TODO sqlitecloud-js / implement database loadExtension #17\n if (callback) {\n callback.call(this, new Error('Database.loadExtension - Not implemented'));\n }\n else {\n this.emitEvent('error', new Error('Database.loadExtension - Not implemented'));\n }\n return this;\n }\n /**\n * Allows the user to interrupt long-running queries. Wrapper around\n * sqlite3_interrupt and causes other data-fetching functions to be\n * passed an err with code = sqlite3.INTERRUPT. The database must be\n * open to use this function.\n */\n interrupt() {\n // TODO sqlitecloud-js / implement database interrupt #13\n }\n //\n // extended APIs\n //\n /**\n * Sql is a promise based API for executing SQL statements. You can\n * pass a simple string with a SQL statement or a template string\n * using backticks and parameters in ${parameter} format. These parameters\n * will be properly escaped and quoted like when using a prepared statement.\n * @param sql A sql string or a template string in `backticks` format\n * @returns An array of rows in case of selections or an object with\n * metadata in case of insert, update, delete.\n */\n sql(sql, ...values) {\n return __awaiter(this, void 0, void 0, function* () {\n let preparedSql = '';\n // sql is a TemplateStringsArray, the 'raw' property is specific to TemplateStringsArray\n if (Array.isArray(sql) && 'raw' in sql) {\n sql.forEach((string, i) => {\n preparedSql += string + (i < values.length ? '?' : '');\n });\n preparedSql = (0, utilities_1.prepareSql)(preparedSql, ...values);\n }\n else {\n if (typeof sql === 'string') {\n if ((values === null || values === void 0 ? void 0 : values.length) > 0) {\n preparedSql = (0, utilities_1.prepareSql)(sql, ...values);\n }\n else {\n preparedSql = sql;\n }\n }\n else {\n throw new Error('Invalid sql');\n }\n }\n return new Promise((resolve, reject) => {\n this.getConnection((error, connection) => {\n if (error || !connection) {\n reject(error);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n reject(error);\n }\n else {\n // metadata for operations like insert, update, delete?\n const context = this.processContext(results);\n resolve(context ? context : results);\n }\n });\n }\n });\n });\n });\n }\n}\nexports.Database = Database;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/database.js?");
|
|
62
|
+
eval("\n//\n// database.ts - database driver api, implements and extends sqlite3\n//\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Database = void 0;\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst statement_1 = __webpack_require__(/*! ./statement */ \"./lib/drivers/statement.js\");\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst utilities_2 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\n// Uses eventemitter3 instead of node events for browser compatibility\n// https://github.com/primus/eventemitter3\n/**\n * Creating a Database object automatically opens a connection to the SQLite database.\n * When the connection is established the Database object emits an open event and calls\n * the optional provided callback. If the connection cannot be established an error event\n * will be emitted and the optional callback is called with the error information.\n */\nclass Database extends eventemitter3_1.default {\n constructor(config, mode, callback) {\n super();\n /** Database connections */\n this.connections = [];\n this.config = typeof config === 'string' ? { connectionstring: config } : config;\n // mode is optional and so is callback\n // https://github.com/TryGhost/node-sqlite3/wiki/API#new-sqlite3databasefilename--mode--callback\n if (typeof mode === 'function') {\n callback = mode;\n mode = undefined;\n }\n // mode is ignored for now\n // opens first connection to the database automatically\n this.getConnection((error, _connection) => {\n if (callback) {\n callback.call(this, error);\n }\n });\n }\n //\n // private methods\n //\n /** Returns first available connection from connection pool */\n getConnection(callback) {\n var _a, _b, _c;\n // TODO sqlitecloud-js / implement database connection pool #10\n if (((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n }\n else {\n // connect using websocket if tls is not supported or if explicitly requested\n const useWebsocket = utilities_2.isBrowser || ((_b = this.config) === null || _b === void 0 ? void 0 : _b.usewebsocket) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.gatewayurl);\n if (useWebsocket) {\n // socket.io transport works in both node.js and browser environments and connects via SQLite Cloud Gateway\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-ws */ \"./lib/drivers/connection-ws.js\"))).then(module => {\n this.connections.push(new module.default(this.config, error => {\n if (error) {\n this.handleError(this.connections[0], error, callback);\n }\n else {\n console.assert;\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n this.emitEvent('open');\n }\n }));\n })\n .catch(error => {\n this.handleError(null, error, callback);\n });\n }\n else {\n // tls sockets work only in node.js environments\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-tls */ \"./lib/drivers/connection-tls.js\"))).then(module => {\n this.connections.push(new module.default(this.config, error => {\n if (error) {\n this.handleError(this.connections[0], error, callback);\n }\n else {\n console.assert;\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n this.emitEvent('open');\n }\n }));\n })\n .catch(error => {\n this.handleError(null, error, callback);\n });\n }\n }\n }\n /** Handles an error by closing the connection, calling the callback and/or emitting an error event */\n handleError(connection, error, callback) {\n // an errored connection is thrown out\n if (connection) {\n this.connections = this.connections.filter(c => c !== connection);\n connection.close();\n }\n if (callback) {\n callback.call(this, error);\n }\n else {\n this.emitEvent('error', error);\n }\n }\n /**\n * Some queries like inserts or updates processed via run or exec may generate\n * an empty result (eg. no data was selected), but still have some metadata.\n * For example the server may pass the id of the last row that was modified.\n * In this case the callback results should be empty but the context may contain\n * additional information like lastID, etc.\n * @see https://github.com/TryGhost/node-sqlite3/wiki/API#runsql--param---callback\n * @param results Results received from the server\n * @returns A context object if one makes sense, otherwise undefined\n */\n processContext(results) {\n if (results) {\n if (Array.isArray(results) && results.length > 0) {\n switch (results[0]) {\n case types_1.SQLiteCloudArrayType.ARRAY_TYPE_SQLITE_EXEC:\n return {\n lastID: results[2],\n changes: results[3],\n totalChanges: results[4],\n finalized: results[5] // FINALIZED\n };\n }\n }\n }\n return undefined;\n }\n /** Emits given event with optional arguments on the next tick so callbacks can complete first */\n emitEvent(event, ...args) {\n setTimeout(() => {\n this.emit(event, ...args);\n }, 0);\n }\n //\n // public methods\n //\n /**\n * Returns the configuration with which this database was opened.\n * The configuration is readonly and cannot be changed as there may\n * be multiple connections using the same configuration.\n * @returns {SQLiteCloudConfig} A configuration object\n */\n getConfiguration() {\n return JSON.parse(JSON.stringify(this.config));\n }\n /** Enable verbose mode */\n verbose() {\n this.config.verbose = true;\n for (const connection of this.connections) {\n connection.verbose();\n }\n return this;\n }\n /** Set a configuration option for the database */\n configure(_option, _value) {\n // https://github.com/TryGhost/node-sqlite3/wiki/API#configureoption-value\n return this;\n }\n run(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n // context may include id of last row inserted, total changes, etc...\n const context = this.processContext(results);\n callback === null || callback === void 0 ? void 0 : callback.call(context || this, null, context ? context : results);\n }\n });\n }\n });\n return this;\n }\n get(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (results && results instanceof rowset_1.SQLiteCloudRowset && results.length > 0) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, results[0]);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n }\n });\n }\n });\n return this;\n }\n all(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (results && results instanceof rowset_1.SQLiteCloudRowset) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, results);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n }\n });\n }\n });\n return this;\n }\n each(sql, ...params) {\n // extract optional parameters and one or two callbacks\n const { args, callback, complete } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, rowset) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (rowset && rowset instanceof rowset_1.SQLiteCloudRowset) {\n if (callback) {\n for (const row of rowset) {\n callback.call(this, null, row);\n }\n }\n if (complete) {\n ;\n complete.call(this, null, rowset.numberOfRows);\n }\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Invalid rowset'));\n }\n }\n });\n }\n });\n return this;\n }\n /**\n * Prepares the SQL statement and optionally binds the specified parameters and\n * calls the callback when done. The function returns a Statement object.\n * When preparing was successful, the first and only argument to the callback\n * is null, otherwise it is the error object. When bind parameters are supplied,\n * they are bound to the prepared statement before calling the callback.\n */\n prepare(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n return new statement_1.Statement(this, sql, ...args, callback);\n }\n /**\n * Runs all SQL queries in the supplied string. No result rows are retrieved.\n * The function returns the Database object to allow for function chaining.\n * If a query fails, no subsequent statements will be executed (wrap it in a\n * transaction if you want all or none to be executed). When all statements\n * have been executed successfully, or when an error occurs, the callback\n * function is called, with the first parameter being either null or an error\n * object. When no callback is provided and an error occurs, an error event\n * will be emitted on the database object.\n */\n exec(sql, callback) {\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(sql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n const context = this.processContext(results);\n callback === null || callback === void 0 ? void 0 : callback.call(context ? context : this, null);\n }\n });\n }\n });\n return this;\n }\n /**\n * If the optional callback is provided, this function will be called when the\n * database was closed successfully or when an error occurred. The first argument\n * is an error object. When it is null, closing succeeded. If no callback is provided\n * and an error occurred, an error event with the error object as the only parameter\n * will be emitted on the database object. If closing succeeded, a close event with no\n * parameters is emitted, regardless of whether a callback was provided or not.\n */\n close(callback) {\n var _a;\n if (((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0) {\n for (const connection of this.connections) {\n connection.close();\n }\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n this.emitEvent('close');\n }\n /**\n * Loads a compiled SQLite extension into the database connection object.\n * @param path Filename of the extension to load.\n * @param callback If provided, this function will be called when the extension\n * was loaded successfully or when an error occurred. The first argument is an\n * error object. When it is null, loading succeeded. If no callback is provided\n * and an error occurred, an error event with the error object as the only parameter\n * will be emitted on the database object.\n */\n loadExtension(_path, callback) {\n // TODO sqlitecloud-js / implement database loadExtension #17\n if (callback) {\n callback.call(this, new Error('Database.loadExtension - Not implemented'));\n }\n else {\n this.emitEvent('error', new Error('Database.loadExtension - Not implemented'));\n }\n return this;\n }\n /**\n * Allows the user to interrupt long-running queries. Wrapper around\n * sqlite3_interrupt and causes other data-fetching functions to be\n * passed an err with code = sqlite3.INTERRUPT. The database must be\n * open to use this function.\n */\n interrupt() {\n // TODO sqlitecloud-js / implement database interrupt #13\n }\n //\n // extended APIs\n //\n /**\n * Sql is a promise based API for executing SQL statements. You can\n * pass a simple string with a SQL statement or a template string\n * using backticks and parameters in ${parameter} format. These parameters\n * will be properly escaped and quoted like when using a prepared statement.\n * @param sql A sql string or a template string in `backticks` format\n * @returns An array of rows in case of selections or an object with\n * metadata in case of insert, update, delete.\n */\n sql(sql, ...values) {\n return __awaiter(this, void 0, void 0, function* () {\n let preparedSql = '';\n // sql is a TemplateStringsArray, the 'raw' property is specific to TemplateStringsArray\n if (Array.isArray(sql) && 'raw' in sql) {\n sql.forEach((string, i) => {\n preparedSql += string + (i < values.length ? '?' : '');\n });\n preparedSql = (0, utilities_1.prepareSql)(preparedSql, ...values);\n }\n else {\n if (typeof sql === 'string') {\n if ((values === null || values === void 0 ? void 0 : values.length) > 0) {\n preparedSql = (0, utilities_1.prepareSql)(sql, ...values);\n }\n else {\n preparedSql = sql;\n }\n }\n else {\n throw new Error('Invalid sql');\n }\n }\n return new Promise((resolve, reject) => {\n this.getConnection((error, connection) => {\n if (error || !connection) {\n reject(error);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n reject(error);\n }\n else {\n // metadata for operations like insert, update, delete?\n const context = this.processContext(results);\n resolve(context ? context : results);\n }\n });\n }\n });\n });\n });\n }\n}\nexports.Database = Database;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/database.js?");
|
|
63
63
|
|
|
64
64
|
/***/ }),
|
|
65
65
|
|
|
@@ -125,7 +125,7 @@ eval("\n/**\n * types.ts - shared types and interfaces\n */\nObject.defineProper
|
|
|
125
125
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
126
126
|
|
|
127
127
|
"use strict";
|
|
128
|
-
eval("\n//\n// utilities.ts - utility methods to manipulate SQL statements\n//\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.parseBoolean = exports.parseConnectionString = exports.validateConfiguration = exports.popCallback = exports.prepareSql = exports.escapeSqlParameter = exports.getInitializationCommands = exports.anonimizeError = exports.anonimizeCommand = exports.isNode = exports.isBrowser = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\n//\n// determining running environment, thanks to browser-or-node\n// https://www.npmjs.com/package/browser-or-node\n//\nexports.isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\nexports.isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;\n//\n// utility methods\n//\n/** Messages going to the server are sometimes logged when error conditions occour and need to be stripped of user credentials */\nfunction anonimizeCommand(message) {\n // hide password in AUTH command if needed\n message = message.replace(/USER \\S+/, 'USER ******');\n message = message.replace(/PASSWORD \\S+?(?=;)/, 'PASSWORD ******');\n message = message.replace(/HASH \\S+?(?=;)/, 'HASH ******');\n return message;\n}\nexports.anonimizeCommand = anonimizeCommand;\n/** Strip message code in error of user credentials */\nfunction anonimizeError(error) {\n if (error === null || error === void 0 ? void 0 : error.message) {\n error.message = anonimizeCommand(error.message);\n }\n return error;\n}\nexports.anonimizeError = anonimizeError;\n/** Initialization commands sent to database when connection is established */\nfunction getInitializationCommands(config) {\n // first user authentication, then all other commands\n let commands = `AUTH USER ${config.username || ''} ${config.passwordHashed ? 'HASH' : 'PASSWORD'} ${config.password || ''}; `;\n if (config.database) {\n if (config.createDatabase && !config.dbMemory) {\n commands += `CREATE DATABASE ${config.database} IF NOT EXISTS; `;\n }\n commands += `USE DATABASE ${config.database}; `;\n }\n if (config.compression) {\n commands += 'SET CLIENT KEY COMPRESSION TO 1; ';\n }\n if (config.nonlinearizable) {\n commands += 'SET CLIENT KEY NONLINEARIZABLE TO 1; ';\n }\n if (config.noBlob) {\n commands += 'SET CLIENT KEY NOBLOB TO 1; ';\n }\n if (config.maxData) {\n commands += `SET CLIENT KEY MAXDATA TO ${config.maxData}; `;\n }\n if (config.maxRows) {\n commands += `SET CLIENT KEY MAXROWS TO ${config.maxRows}; `;\n }\n if (config.maxRowset) {\n commands += `SET CLIENT KEY MAXROWSET TO ${config.maxRowset}; `;\n }\n return commands;\n}\nexports.getInitializationCommands = getInitializationCommands;\n/** Takes a generic value and escapes it so it can replace ? as a binding in a prepared SQL statement */\nfunction escapeSqlParameter(param) {\n if (param === null || param === undefined) {\n return 'NULL';\n }\n if (typeof param === 'string') {\n // replace single quote with two single quotes\n param = param.replace(/'/g, \"''\");\n return `'${param}'`;\n }\n if (typeof param === 'number') {\n return param.toString();\n }\n if (typeof param === 'boolean') {\n return param ? '1' : '0';\n }\n // serialize buffer as X'...' hex encoded string\n if (Buffer.isBuffer(param)) {\n return `X'${param.toString('hex')}'`;\n }\n if (typeof param === 'object') {\n // serialize json then escape single quotes\n let json = JSON.stringify(param);\n json = json.replace(/'/g, \"''\");\n return `'${json}'`;\n }\n throw new types_1.SQLiteCloudError(`Unsupported parameter type: ${typeof param}`);\n}\nexports.escapeSqlParameter = escapeSqlParameter;\n/** Take a sql statement and replaces ? or $named parameters that are properly serialized and escaped. */\nfunction prepareSql(sql, ...params) {\n // parameters where passed as an array of parameters?\n if ((params === null || params === void 0 ? void 0 : params.length) === 1 && Array.isArray(params[0])) {\n params = params[0];\n }\n // replace ? or ?idx parameters passed as args or as an array\n let parameterIndex = 1;\n let preparedSql = sql.replace(/\\?(\\d+)?/g, (match, matchIndex) => {\n const index = matchIndex ? parseInt(matchIndex) : parameterIndex;\n parameterIndex++;\n let sqlParameter;\n if (params[0] && typeof params[0] === 'object' && !(params[0] instanceof Buffer)) {\n sqlParameter = params[0][index];\n }\n if (!sqlParameter) {\n if (index > params.length) {\n throw new types_1.SQLiteCloudError('Not enough parameters');\n }\n sqlParameter = params[index - 1];\n }\n return sqlParameter !== null && sqlParameter !== undefined ? escapeSqlParameter(sqlParameter) : 'NULL';\n });\n // replace $named or :named parameters passed as an object\n if ((params === null || params === void 0 ? void 0 : params.length) === 1 && params[0] && typeof params[0] === 'object') {\n const namedParams = params[0];\n for (const [paramKey, param] of Object.entries(namedParams)) {\n const firstChar = paramKey.charAt(0);\n if (firstChar == '$' || firstChar == ':' || firstChar == '@') {\n const escapedParam = escapeSqlParameter(param);\n preparedSql = preparedSql.replace(new RegExp(`\\\\${paramKey}`, 'g'), escapedParam);\n }\n }\n }\n return preparedSql;\n}\nexports.prepareSql = prepareSql;\n/**\n * Many of the methods in our API may contain a callback as their last argument.\n * This method will take the arguments array passed to the method and return an object\n * containing the arguments array with the callbacks removed (if any), and the callback itself.\n * If there are multiple callbacks, the first one is returned as 'callback' and the last one\n * as 'completeCallback'.\n */\nfunction popCallback(args) {\n const remaining = args;\n // at least 1 callback?\n if (args && args.length > 0 && typeof args[args.length - 1] === 'function') {\n // at least 2 callbacks?\n if (args.length > 1 && typeof args[args.length - 2] === 'function') {\n return { args: remaining.slice(0, -2), callback: args[args.length - 2], complete: args[args.length - 1] };\n }\n return { args: remaining.slice(0, -1), callback: args[args.length - 1] };\n }\n return { args: remaining };\n}\nexports.popCallback = popCallback;\n//\n// configuration validation\n//\n/** Validate configuration, apply defaults, throw if something is missing or misconfigured */\nfunction validateConfiguration(config) {\n console.assert(config, 'SQLiteCloudConnection.validateConfiguration - missing config');\n if (config.connectionString) {\n config = Object.assign(Object.assign(Object.assign({}, config), parseConnectionString(config.connectionString)), { connectionString: config.connectionString // keep original connection string\n });\n }\n // apply defaults where needed\n config.port || (config.port = types_1.DEFAULT_PORT);\n config.timeout = config.timeout && config.timeout > 0 ? config.timeout : types_1.DEFAULT_TIMEOUT;\n config.clientId || (config.clientId = 'SQLiteCloud');\n config.verbose = parseBoolean(config.verbose);\n config.noBlob = parseBoolean(config.noBlob);\n config.compression = parseBoolean(config.compression);\n config.createDatabase = parseBoolean(config.createDatabase);\n config.nonlinearizable = parseBoolean(config.nonlinearizable);\n config.insecure = parseBoolean(config.insecure);\n if (!config.username || !config.password || !config.host) {\n console.error('SQLiteCloudConnection.validateConfiguration - missing arguments', config);\n throw new types_1.SQLiteCloudError('The user, password and host arguments must be specified.', { errorCode: 'ERR_MISSING_ARGS' });\n }\n if (!config.connectionString) {\n // build connection string from configuration, values are already validated\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n config.connectionString = `sqlitecloud://${encodeURIComponent(config.username)}:${encodeURIComponent(config.password)}@${config.host}:${config.port}/${config.database}`;\n }\n return config;\n}\nexports.validateConfiguration = validateConfiguration;\n/** Parse connectionString like sqlitecloud://username:password@host:port/database?option1=xxx&option2=xxx into its components */\nfunction parseConnectionString(connectionString) {\n try {\n // The URL constructor throws a TypeError if the URL is not valid.\n // in spite of having the same structure as a regular url\n // protocol://username:password@host:port/database?option1=xxx&option2=xxx)\n // the sqlitecloud: protocol is not recognized by the URL constructor in browsers\n // so we need to replace it with https: to make it work\n const knownProtocolUrl = connectionString.replace('sqlitecloud:', 'https:');\n const url = new URL(knownProtocolUrl);\n const options = {};\n url.searchParams.forEach((value, key) => {\n options[key] = value;\n });\n const config = Object.assign({ username: decodeURIComponent(url.username), password: decodeURIComponent(url.password), host: url.hostname, port: url.port ? parseInt(url.port) : undefined }, options);\n const database = url.pathname.replace('/', ''); // pathname is database name, remove the leading slash\n if (database) {\n config.database = database;\n }\n return config;\n }\n catch (error) {\n throw new types_1.SQLiteCloudError(`Invalid connection string: ${connectionString}`);\n }\n}\nexports.parseConnectionString = parseConnectionString;\n/** Returns true if value is 1 or true */\nfunction parseBoolean(value) {\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true' || value === '1';\n }\n return value ? true : false;\n}\nexports.parseBoolean = parseBoolean;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/utilities.js?");
|
|
128
|
+
eval("\n//\n// utilities.ts - utility methods to manipulate SQL statements\n//\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.parseBooleanToZeroOne = exports.parseBoolean = exports.parseconnectionstring = exports.validateConfiguration = exports.popCallback = exports.getUpdateResults = exports.prepareSql = exports.escapeSqlParameter = exports.getInitializationCommands = exports.anonimizeError = exports.anonimizeCommand = exports.isNode = exports.isBrowser = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst types_2 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\n//\n// determining running environment, thanks to browser-or-node\n// https://www.npmjs.com/package/browser-or-node\n//\nexports.isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\nexports.isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;\n//\n// utility methods\n//\n/** Messages going to the server are sometimes logged when error conditions occour and need to be stripped of user credentials */\nfunction anonimizeCommand(message) {\n // hide password in AUTH command if needed\n message = message.replace(/USER \\S+/, 'USER ******');\n message = message.replace(/PASSWORD \\S+?(?=;)/, 'PASSWORD ******');\n message = message.replace(/HASH \\S+?(?=;)/, 'HASH ******');\n return message;\n}\nexports.anonimizeCommand = anonimizeCommand;\n/** Strip message code in error of user credentials */\nfunction anonimizeError(error) {\n if (error === null || error === void 0 ? void 0 : error.message) {\n error.message = anonimizeCommand(error.message);\n }\n return error;\n}\nexports.anonimizeError = anonimizeError;\n/** Initialization commands sent to database when connection is established */\nfunction getInitializationCommands(config) {\n // we check the credentials using non linearizable so we're quicker\n // then we bring back linearizability unless specified otherwise\n let commands = 'SET CLIENT KEY NONLINEARIZABLE TO 1; ';\n // first user authentication, then all other commands\n if (config.apikey) {\n commands += `AUTH APIKEY ${config.apikey}; `;\n }\n else {\n commands += `AUTH USER ${config.username || ''} ${config.password_hashed ? 'HASH' : 'PASSWORD'} ${config.password || ''}; `;\n }\n if (config.compression) {\n commands += 'SET CLIENT KEY COMPRESSION TO 1; ';\n }\n if (config.zerotext) {\n commands += 'SET CLIENT KEY ZEROTEXT TO 1; ';\n }\n if (config.noblob) {\n commands += 'SET CLIENT KEY NOBLOB TO 1; ';\n }\n if (config.maxdata) {\n commands += `SET CLIENT KEY MAXDATA TO ${config.maxdata}; `;\n }\n if (config.maxrows) {\n commands += `SET CLIENT KEY MAXROWS TO ${config.maxrows}; `;\n }\n if (config.maxrowset) {\n commands += `SET CLIENT KEY MAXROWSET TO ${config.maxrowset}; `;\n }\n // we ALWAYS set non linearizable to 1 when we start so we can be quicker on login\n // but then we need to put it back to its default value if \"linearizable\" unless set\n if (!config.non_linearizable) {\n commands += 'SET CLIENT KEY NONLINEARIZABLE TO 0; ';\n }\n if (config.database) {\n if (config.create && !config.memory) {\n commands += `CREATE DATABASE ${config.database} IF NOT EXISTS; `;\n }\n commands += `USE DATABASE ${config.database}; `;\n }\n return commands;\n}\nexports.getInitializationCommands = getInitializationCommands;\n/** Takes a generic value and escapes it so it can replace ? as a binding in a prepared SQL statement */\nfunction escapeSqlParameter(param) {\n if (param === null || param === undefined) {\n return 'NULL';\n }\n if (typeof param === 'string') {\n // replace single quote with two single quotes\n param = param.replace(/'/g, \"''\");\n return `'${param}'`;\n }\n if (typeof param === 'number' || typeof param === 'bigint') {\n return param.toString();\n }\n if (typeof param === 'boolean') {\n return param ? '1' : '0';\n }\n // serialize buffer as X'...' hex encoded string\n if (Buffer.isBuffer(param)) {\n return `X'${param.toString('hex')}'`;\n }\n if (typeof param === 'object') {\n // serialize json then escape single quotes\n let json = JSON.stringify(param);\n json = json.replace(/'/g, \"''\");\n return `'${json}'`;\n }\n throw new types_1.SQLiteCloudError(`Unsupported parameter type: ${typeof param}`);\n}\nexports.escapeSqlParameter = escapeSqlParameter;\n/** Take a sql statement and replaces ? or $named parameters that are properly serialized and escaped. */\nfunction prepareSql(sql, ...params) {\n // parameters where passed as an array of parameters?\n if ((params === null || params === void 0 ? void 0 : params.length) === 1 && Array.isArray(params[0])) {\n params = params[0];\n }\n // replace ? or ?idx parameters passed as args or as an array\n let parameterIndex = 1;\n let preparedSql = sql.replace(/\\?(\\d+)?/g, (match, matchIndex) => {\n const index = matchIndex ? parseInt(matchIndex) : parameterIndex;\n parameterIndex++;\n let sqlParameter;\n if (params[0] && typeof params[0] === 'object' && !(params[0] instanceof Buffer)) {\n sqlParameter = params[0][index];\n }\n if (!sqlParameter) {\n if (index > params.length) {\n throw new types_1.SQLiteCloudError('Not enough parameters');\n }\n sqlParameter = params[index - 1];\n }\n return sqlParameter !== null && sqlParameter !== undefined ? escapeSqlParameter(sqlParameter) : 'NULL';\n });\n // replace $named or :named parameters passed as an object\n if ((params === null || params === void 0 ? void 0 : params.length) === 1 && params[0] && typeof params[0] === 'object') {\n const namedParams = params[0];\n for (const [paramKey, param] of Object.entries(namedParams)) {\n const firstChar = paramKey.charAt(0);\n if (firstChar == '$' || firstChar == ':' || firstChar == '@') {\n const escapedParam = escapeSqlParameter(param);\n preparedSql = preparedSql.replace(new RegExp(`\\\\${paramKey}`, 'g'), escapedParam);\n }\n }\n }\n return preparedSql;\n}\nexports.prepareSql = prepareSql;\n/** Converts results of an update or insert call into a more meaning full result set */\nfunction getUpdateResults(results) {\n if (results) {\n if (Array.isArray(results) && results.length > 0) {\n switch (results[0]) {\n case types_2.SQLiteCloudArrayType.ARRAY_TYPE_SQLITE_EXEC:\n return {\n type: results[0],\n index: results[1],\n lastID: results[2],\n changes: results[3],\n totalChanges: results[4],\n finalized: results[5],\n //\n rowId: results[2] // same as lastId\n };\n }\n }\n }\n return undefined;\n}\nexports.getUpdateResults = getUpdateResults;\n/**\n * Many of the methods in our API may contain a callback as their last argument.\n * This method will take the arguments array passed to the method and return an object\n * containing the arguments array with the callbacks removed (if any), and the callback itself.\n * If there are multiple callbacks, the first one is returned as 'callback' and the last one\n * as 'completeCallback'.\n */\nfunction popCallback(args) {\n const remaining = args;\n // at least 1 callback?\n if (args && args.length > 0 && typeof args[args.length - 1] === 'function') {\n // at least 2 callbacks?\n if (args.length > 1 && typeof args[args.length - 2] === 'function') {\n return { args: remaining.slice(0, -2), callback: args[args.length - 2], complete: args[args.length - 1] };\n }\n return { args: remaining.slice(0, -1), callback: args[args.length - 1] };\n }\n return { args: remaining };\n}\nexports.popCallback = popCallback;\n//\n// configuration validation\n//\n/** Validate configuration, apply defaults, throw if something is missing or misconfigured */\nfunction validateConfiguration(config) {\n console.assert(config, 'SQLiteCloudConnection.validateConfiguration - missing config');\n if (config.connectionstring) {\n config = Object.assign(Object.assign(Object.assign({}, config), parseconnectionstring(config.connectionstring)), { connectionstring: config.connectionstring // keep original connection string\n });\n }\n // apply defaults where needed\n config.port || (config.port = types_1.DEFAULT_PORT);\n config.timeout = config.timeout && config.timeout > 0 ? config.timeout : types_1.DEFAULT_TIMEOUT;\n config.clientid || (config.clientid = 'SQLiteCloud');\n config.verbose = parseBoolean(config.verbose);\n config.noblob = parseBoolean(config.noblob);\n config.compression = parseBoolean(config.compression);\n config.create = parseBoolean(config.create);\n config.non_linearizable = parseBoolean(config.non_linearizable);\n config.insecure = parseBoolean(config.insecure);\n const hasCredentials = (config.username && config.password) || config.apikey;\n if (!config.host || !hasCredentials) {\n console.error('SQLiteCloudConnection.validateConfiguration - missing arguments', config);\n throw new types_1.SQLiteCloudError('The user, password and host arguments or the ?apikey= must be specified.', { errorCode: 'ERR_MISSING_ARGS' });\n }\n if (!config.connectionstring) {\n // build connection string from configuration, values are already validated\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n if (config.apikey) {\n config.connectionstring = `sqlitecloud://${config.host}:${config.port}/${config.database || ''}?apikey=${config.apikey}`;\n }\n else {\n config.connectionstring = `sqlitecloud://${encodeURIComponent(config.username || '')}:${encodeURIComponent(config.password || '')}@${config.host}:${config.port}/${config.database}`;\n }\n }\n return config;\n}\nexports.validateConfiguration = validateConfiguration;\n/**\n * Parse connectionstring like sqlitecloud://username:password@host:port/database?option1=xxx&option2=xxx\n * or sqlitecloud://host.sqlite.cloud:8860/chinook.sqlite?apikey=mIiLARzKm9XBVllbAzkB1wqrgijJ3Gx0X5z1Agm3xBo\n * into its basic components.\n */\nfunction parseconnectionstring(connectionstring) {\n try {\n // The URL constructor throws a TypeError if the URL is not valid.\n // in spite of having the same structure as a regular url\n // protocol://username:password@host:port/database?option1=xxx&option2=xxx)\n // the sqlitecloud: protocol is not recognized by the URL constructor in browsers\n // so we need to replace it with https: to make it work\n const knownProtocolUrl = connectionstring.replace('sqlitecloud:', 'https:');\n const url = new URL(knownProtocolUrl);\n // all lowecase options\n const options = {};\n url.searchParams.forEach((value, key) => {\n options[key.toLowerCase().replaceAll('-', '_')] = value;\n });\n const config = Object.assign({ username: decodeURIComponent(url.username), password: decodeURIComponent(url.password), host: url.hostname, port: url.port ? parseInt(url.port) : undefined }, options);\n // either you use an apikey or username and password\n if (config.apikey) {\n if (config.username || config.password) {\n console.warn('SQLiteCloudConnection.parseconnectionstring - apikey and username/password are both specified, using apikey');\n }\n delete config.username;\n delete config.password;\n }\n const database = url.pathname.replace('/', ''); // pathname is database name, remove the leading slash\n if (database) {\n config.database = database;\n }\n return config;\n }\n catch (error) {\n throw new types_1.SQLiteCloudError(`Invalid connection string: ${connectionstring}`);\n }\n}\nexports.parseconnectionstring = parseconnectionstring;\n/** Returns true if value is 1 or true */\nfunction parseBoolean(value) {\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true' || value === '1';\n }\n return value ? true : false;\n}\nexports.parseBoolean = parseBoolean;\n/** Returns true if value is 1 or true */\nfunction parseBooleanToZeroOne(value) {\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true' || value === '1' ? 1 : 0;\n }\n return value ? 1 : 0;\n}\nexports.parseBooleanToZeroOne = parseBooleanToZeroOne;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/utilities.js?");
|
|
129
129
|
|
|
130
130
|
/***/ }),
|
|
131
131
|
|
|
@@ -136,7 +136,7 @@ eval("\n//\n// utilities.ts - utility methods to manipulate SQL statements\n//\n
|
|
|
136
136
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
137
137
|
|
|
138
138
|
"use strict";
|
|
139
|
-
eval("\n//\n// index.ts - export drivers classes, utilities, types\n//\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateConfiguration = exports.
|
|
139
|
+
eval("\n//\n// index.ts - export drivers classes, utilities, types\n//\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateConfiguration = exports.parseconnectionstring = exports.prepareSql = exports.escapeSqlParameter = exports.SQLiteCloudRow = exports.SQLiteCloudRowset = exports.SQLiteCloudError = exports.SQLiteCloudConnection = exports.Statement = exports.Database = void 0;\n// include ONLY packages used by drivers\n// do NOT include anything related to gateway or bun or express\n// connection-tls does not want/need to load on browser and is loaded dynamically by Database\n// connection-ws does not want/need to load on node and is loaded dynamically by Database\nvar database_1 = __webpack_require__(/*! ./drivers/database */ \"./lib/drivers/database.js\");\nObject.defineProperty(exports, \"Database\", ({ enumerable: true, get: function () { return database_1.Database; } }));\nvar statement_1 = __webpack_require__(/*! ./drivers/statement */ \"./lib/drivers/statement.js\");\nObject.defineProperty(exports, \"Statement\", ({ enumerable: true, get: function () { return statement_1.Statement; } }));\nvar connection_1 = __webpack_require__(/*! ./drivers/connection */ \"./lib/drivers/connection.js\");\nObject.defineProperty(exports, \"SQLiteCloudConnection\", ({ enumerable: true, get: function () { return connection_1.SQLiteCloudConnection; } }));\nvar types_1 = __webpack_require__(/*! ./drivers/types */ \"./lib/drivers/types.js\");\nObject.defineProperty(exports, \"SQLiteCloudError\", ({ enumerable: true, get: function () { return types_1.SQLiteCloudError; } }));\nvar rowset_1 = __webpack_require__(/*! ./drivers/rowset */ \"./lib/drivers/rowset.js\");\nObject.defineProperty(exports, \"SQLiteCloudRowset\", ({ enumerable: true, get: function () { return rowset_1.SQLiteCloudRowset; } }));\nObject.defineProperty(exports, \"SQLiteCloudRow\", ({ enumerable: true, get: function () { return rowset_1.SQLiteCloudRow; } }));\nvar utilities_1 = __webpack_require__(/*! ./drivers/utilities */ \"./lib/drivers/utilities.js\");\nObject.defineProperty(exports, \"escapeSqlParameter\", ({ enumerable: true, get: function () { return utilities_1.escapeSqlParameter; } }));\nObject.defineProperty(exports, \"prepareSql\", ({ enumerable: true, get: function () { return utilities_1.prepareSql; } }));\nObject.defineProperty(exports, \"parseconnectionstring\", ({ enumerable: true, get: function () { return utilities_1.parseconnectionstring; } }));\nObject.defineProperty(exports, \"validateConfiguration\", ({ enumerable: true, get: function () { return utilities_1.validateConfiguration; } }));\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/index.js?");
|
|
140
140
|
|
|
141
141
|
/***/ }),
|
|
142
142
|
|
|
@@ -492,7 +492,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
|
|
|
492
492
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
493
493
|
|
|
494
494
|
"use strict";
|
|
495
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Socket = void 0;\nconst socket_io_parser_1 = __webpack_require__(/*! socket.io-parser */ \"./node_modules/socket.io-parser/build/cjs/index.js\");\nconst on_js_1 = __webpack_require__(/*! ./on.js */ \"./node_modules/socket.io-client/build/cjs/on.js\");\nconst component_emitter_1 = __webpack_require__(/*! @socket.io/component-emitter */ \"./node_modules/@socket.io/component-emitter/index.mjs\");\nconst debug_1 = __importDefault(__webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")); // debug()\nconst debug = debug_1.default(\"socket.io-client:socket\"); // debug()\n/**\n * Internal events.\n * These events can't be emitted by the user.\n */\nconst RESERVED_EVENTS = Object.freeze({\n connect: 1,\n connect_error: 1,\n disconnect: 1,\n disconnecting: 1,\n // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener\n newListener: 1,\n removeListener: 1,\n});\n/**\n * A Socket is the fundamental class for interacting with the server.\n *\n * A Socket belongs to a certain Namespace (by default /) and uses an underlying {@link Manager} to communicate.\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"connect\", () => {\n * console.log(\"connected\");\n * });\n *\n * // send an event to the server\n * socket.emit(\"foo\", \"bar\");\n *\n * socket.on(\"foobar\", () => {\n * // an event was received from the server\n * });\n *\n * // upon disconnection\n * socket.on(\"disconnect\", (reason) => {\n * console.log(`disconnected due to ${reason}`);\n * });\n */\nclass Socket extends component_emitter_1.Emitter {\n /**\n * `Socket` constructor.\n */\n constructor(io, nsp, opts) {\n super();\n /**\n * Whether the socket is currently connected to the server.\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"connect\", () => {\n * console.log(socket.connected); // true\n * });\n *\n * socket.on(\"disconnect\", () => {\n * console.log(socket.connected); // false\n * });\n */\n this.connected = false;\n /**\n * Whether the connection state was recovered after a temporary disconnection. In that case, any missed packets will\n * be transmitted by the server.\n */\n this.recovered = false;\n /**\n * Buffer for packets received before the CONNECT packet\n */\n this.receiveBuffer = [];\n /**\n * Buffer for packets that will be sent once the socket is connected\n */\n this.sendBuffer = [];\n /**\n * The queue of packets to be sent with retry in case of failure.\n *\n * Packets are sent one by one, each waiting for the server acknowledgement, in order to guarantee the delivery order.\n * @private\n */\n this._queue = [];\n /**\n * A sequence to generate the ID of the {@link QueuedPacket}.\n * @private\n */\n this._queueSeq = 0;\n this.ids = 0;\n this.acks = {};\n this.flags = {};\n this.io = io;\n this.nsp = nsp;\n if (opts && opts.auth) {\n this.auth = opts.auth;\n }\n this._opts = Object.assign({}, opts);\n if (this.io._autoConnect)\n this.open();\n }\n /**\n * Whether the socket is currently disconnected\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"connect\", () => {\n * console.log(socket.disconnected); // false\n * });\n *\n * socket.on(\"disconnect\", () => {\n * console.log(socket.disconnected); // true\n * });\n */\n get disconnected() {\n return !this.connected;\n }\n /**\n * Subscribe to open, close and packet events\n *\n * @private\n */\n subEvents() {\n if (this.subs)\n return;\n const io = this.io;\n this.subs = [\n on_js_1.on(io, \"open\", this.onopen.bind(this)),\n on_js_1.on(io, \"packet\", this.onpacket.bind(this)),\n on_js_1.on(io, \"error\", this.onerror.bind(this)),\n on_js_1.on(io, \"close\", this.onclose.bind(this)),\n ];\n }\n /**\n * Whether the Socket will try to reconnect when its Manager connects or reconnects.\n *\n * @example\n * const socket = io();\n *\n * console.log(socket.active); // true\n *\n * socket.on(\"disconnect\", (reason) => {\n * if (reason === \"io server disconnect\") {\n * // the disconnection was initiated by the server, you need to manually reconnect\n * console.log(socket.active); // false\n * }\n * // else the socket will automatically try to reconnect\n * console.log(socket.active); // true\n * });\n */\n get active() {\n return !!this.subs;\n }\n /**\n * \"Opens\" the socket.\n *\n * @example\n * const socket = io({\n * autoConnect: false\n * });\n *\n * socket.connect();\n */\n connect() {\n if (this.connected)\n return this;\n this.subEvents();\n if (!this.io[\"_reconnecting\"])\n this.io.open(); // ensure open\n if (\"open\" === this.io._readyState)\n this.onopen();\n return this;\n }\n /**\n * Alias for {@link connect()}.\n */\n open() {\n return this.connect();\n }\n /**\n * Sends a `message` event.\n *\n * This method mimics the WebSocket.send() method.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send\n *\n * @example\n * socket.send(\"hello\");\n *\n * // this is equivalent to\n * socket.emit(\"message\", \"hello\");\n *\n * @return self\n */\n send(...args) {\n args.unshift(\"message\");\n this.emit.apply(this, args);\n return this;\n }\n /**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @example\n * socket.emit(\"hello\", \"world\");\n *\n * // all serializable datastructures are supported (no need to call JSON.stringify)\n * socket.emit(\"hello\", 1, \"2\", { 3: [\"4\"], 5: Uint8Array.from([6]) });\n *\n * // with an acknowledgement from the server\n * socket.emit(\"hello\", \"world\", (val) => {\n * // ...\n * });\n *\n * @return self\n */\n emit(ev, ...args) {\n if (RESERVED_EVENTS.hasOwnProperty(ev)) {\n throw new Error('\"' + ev.toString() + '\" is a reserved event name');\n }\n args.unshift(ev);\n if (this._opts.retries && !this.flags.fromQueue && !this.flags.volatile) {\n this._addToQueue(args);\n return this;\n }\n const packet = {\n type: socket_io_parser_1.PacketType.EVENT,\n data: args,\n };\n packet.options = {};\n packet.options.compress = this.flags.compress !== false;\n // event ack callback\n if (\"function\" === typeof args[args.length - 1]) {\n const id = this.ids++;\n debug(\"emitting packet with ack id %d\", id);\n const ack = args.pop();\n this._registerAckCallback(id, ack);\n packet.id = id;\n }\n const isTransportWritable = this.io.engine &&\n this.io.engine.transport &&\n this.io.engine.transport.writable;\n const discardPacket = this.flags.volatile && (!isTransportWritable || !this.connected);\n if (discardPacket) {\n debug(\"discard packet as the transport is not currently writable\");\n }\n else if (this.connected) {\n this.notifyOutgoingListeners(packet);\n this.packet(packet);\n }\n else {\n this.sendBuffer.push(packet);\n }\n this.flags = {};\n return this;\n }\n /**\n * @private\n */\n _registerAckCallback(id, ack) {\n var _a;\n const timeout = (_a = this.flags.timeout) !== null && _a !== void 0 ? _a : this._opts.ackTimeout;\n if (timeout === undefined) {\n this.acks[id] = ack;\n return;\n }\n // @ts-ignore\n const timer = this.io.setTimeoutFn(() => {\n delete this.acks[id];\n for (let i = 0; i < this.sendBuffer.length; i++) {\n if (this.sendBuffer[i].id === id) {\n debug(\"removing packet with ack id %d from the buffer\", id);\n this.sendBuffer.splice(i, 1);\n }\n }\n debug(\"event with ack id %d has timed out after %d ms\", id, timeout);\n ack.call(this, new Error(\"operation has timed out\"));\n }, timeout);\n this.acks[id] = (...args) => {\n // @ts-ignore\n this.io.clearTimeoutFn(timer);\n ack.apply(this, [null, ...args]);\n };\n }\n /**\n * Emits an event and waits for an acknowledgement\n *\n * @example\n * // without timeout\n * const response = await socket.emitWithAck(\"hello\", \"world\");\n *\n * // with a specific timeout\n * try {\n * const response = await socket.timeout(1000).emitWithAck(\"hello\", \"world\");\n * } catch (err) {\n * // the server did not acknowledge the event in the given delay\n * }\n *\n * @return a Promise that will be fulfilled when the server acknowledges the event\n */\n emitWithAck(ev, ...args) {\n // the timeout flag is optional\n const withErr = this.flags.timeout !== undefined || this._opts.ackTimeout !== undefined;\n return new Promise((resolve, reject) => {\n args.push((arg1, arg2) => {\n if (withErr) {\n return arg1 ? reject(arg1) : resolve(arg2);\n }\n else {\n return resolve(arg1);\n }\n });\n this.emit(ev, ...args);\n });\n }\n /**\n * Add the packet to the queue.\n * @param args\n * @private\n */\n _addToQueue(args) {\n let ack;\n if (typeof args[args.length - 1] === \"function\") {\n ack = args.pop();\n }\n const packet = {\n id: this._queueSeq++,\n tryCount: 0,\n pending: false,\n args,\n flags: Object.assign({ fromQueue: true }, this.flags),\n };\n args.push((err, ...responseArgs) => {\n if (packet !== this._queue[0]) {\n // the packet has already been acknowledged\n return;\n }\n const hasError = err !== null;\n if (hasError) {\n if (packet.tryCount > this._opts.retries) {\n debug(\"packet [%d] is discarded after %d tries\", packet.id, packet.tryCount);\n this._queue.shift();\n if (ack) {\n ack(err);\n }\n }\n }\n else {\n debug(\"packet [%d] was successfully sent\", packet.id);\n this._queue.shift();\n if (ack) {\n ack(null, ...responseArgs);\n }\n }\n packet.pending = false;\n return this._drainQueue();\n });\n this._queue.push(packet);\n this._drainQueue();\n }\n /**\n * Send the first packet of the queue, and wait for an acknowledgement from the server.\n * @param force - whether to resend a packet that has not been acknowledged yet\n *\n * @private\n */\n _drainQueue(force = false) {\n debug(\"draining queue\");\n if (!this.connected || this._queue.length === 0) {\n return;\n }\n const packet = this._queue[0];\n if (packet.pending && !force) {\n debug(\"packet [%d] has already been sent and is waiting for an ack\", packet.id);\n return;\n }\n packet.pending = true;\n packet.tryCount++;\n debug(\"sending packet [%d] (try n°%d)\", packet.id, packet.tryCount);\n this.flags = packet.flags;\n this.emit.apply(this, packet.args);\n }\n /**\n * Sends a packet.\n *\n * @param packet\n * @private\n */\n packet(packet) {\n packet.nsp = this.nsp;\n this.io._packet(packet);\n }\n /**\n * Called upon engine `open`.\n *\n * @private\n */\n onopen() {\n debug(\"transport is open - connecting\");\n if (typeof this.auth == \"function\") {\n this.auth((data) => {\n this._sendConnectPacket(data);\n });\n }\n else {\n this._sendConnectPacket(this.auth);\n }\n }\n /**\n * Sends a CONNECT packet to initiate the Socket.IO session.\n *\n * @param data\n * @private\n */\n _sendConnectPacket(data) {\n this.packet({\n type: socket_io_parser_1.PacketType.CONNECT,\n data: this._pid\n ? Object.assign({ pid: this._pid, offset: this._lastOffset }, data)\n : data,\n });\n }\n /**\n * Called upon engine or manager `error`.\n *\n * @param err\n * @private\n */\n onerror(err) {\n if (!this.connected) {\n this.emitReserved(\"connect_error\", err);\n }\n }\n /**\n * Called upon engine `close`.\n *\n * @param reason\n * @param description\n * @private\n */\n onclose(reason, description) {\n debug(\"close (%s)\", reason);\n this.connected = false;\n delete this.id;\n this.emitReserved(\"disconnect\", reason, description);\n }\n /**\n * Called with socket packet.\n *\n * @param packet\n * @private\n */\n onpacket(packet) {\n const sameNamespace = packet.nsp === this.nsp;\n if (!sameNamespace)\n return;\n switch (packet.type) {\n case socket_io_parser_1.PacketType.CONNECT:\n if (packet.data && packet.data.sid) {\n this.onconnect(packet.data.sid, packet.data.pid);\n }\n else {\n this.emitReserved(\"connect_error\", new Error(\"It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)\"));\n }\n break;\n case socket_io_parser_1.PacketType.EVENT:\n case socket_io_parser_1.PacketType.BINARY_EVENT:\n this.onevent(packet);\n break;\n case socket_io_parser_1.PacketType.ACK:\n case socket_io_parser_1.PacketType.BINARY_ACK:\n this.onack(packet);\n break;\n case socket_io_parser_1.PacketType.DISCONNECT:\n this.ondisconnect();\n break;\n case socket_io_parser_1.PacketType.CONNECT_ERROR:\n this.destroy();\n const err = new Error(packet.data.message);\n // @ts-ignore\n err.data = packet.data.data;\n this.emitReserved(\"connect_error\", err);\n break;\n }\n }\n /**\n * Called upon a server event.\n *\n * @param packet\n * @private\n */\n onevent(packet) {\n const args = packet.data || [];\n debug(\"emitting event %j\", args);\n if (null != packet.id) {\n debug(\"attaching ack callback to event\");\n args.push(this.ack(packet.id));\n }\n if (this.connected) {\n this.emitEvent(args);\n }\n else {\n this.receiveBuffer.push(Object.freeze(args));\n }\n }\n emitEvent(args) {\n if (this._anyListeners && this._anyListeners.length) {\n const listeners = this._anyListeners.slice();\n for (const listener of listeners) {\n listener.apply(this, args);\n }\n }\n super.emit.apply(this, args);\n if (this._pid && args.length && typeof args[args.length - 1] === \"string\") {\n this._lastOffset = args[args.length - 1];\n }\n }\n /**\n * Produces an ack callback to emit with an event.\n *\n * @private\n */\n ack(id) {\n const self = this;\n let sent = false;\n return function (...args) {\n // prevent double callbacks\n if (sent)\n return;\n sent = true;\n debug(\"sending ack %j\", args);\n self.packet({\n type: socket_io_parser_1.PacketType.ACK,\n id: id,\n data: args,\n });\n };\n }\n /**\n * Called upon a server acknowlegement.\n *\n * @param packet\n * @private\n */\n onack(packet) {\n const ack = this.acks[packet.id];\n if (\"function\" === typeof ack) {\n debug(\"calling ack %s with %j\", packet.id, packet.data);\n ack.apply(this, packet.data);\n delete this.acks[packet.id];\n }\n else {\n debug(\"bad ack %s\", packet.id);\n }\n }\n /**\n * Called upon server connect.\n *\n * @private\n */\n onconnect(id, pid) {\n debug(\"socket connected with id %s\", id);\n this.id = id;\n this.recovered = pid && this._pid === pid;\n this._pid = pid; // defined only if connection state recovery is enabled\n this.connected = true;\n this.emitBuffered();\n this.emitReserved(\"connect\");\n this._drainQueue(true);\n }\n /**\n * Emit buffered events (received and emitted).\n *\n * @private\n */\n emitBuffered() {\n this.receiveBuffer.forEach((args) => this.emitEvent(args));\n this.receiveBuffer = [];\n this.sendBuffer.forEach((packet) => {\n this.notifyOutgoingListeners(packet);\n this.packet(packet);\n });\n this.sendBuffer = [];\n }\n /**\n * Called upon server disconnect.\n *\n * @private\n */\n ondisconnect() {\n debug(\"server disconnect (%s)\", this.nsp);\n this.destroy();\n this.onclose(\"io server disconnect\");\n }\n /**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @private\n */\n destroy() {\n if (this.subs) {\n // clean subscriptions to avoid reconnections\n this.subs.forEach((subDestroy) => subDestroy());\n this.subs = undefined;\n }\n this.io[\"_destroy\"](this);\n }\n /**\n * Disconnects the socket manually. In that case, the socket will not try to reconnect.\n *\n * If this is the last active Socket instance of the {@link Manager}, the low-level connection will be closed.\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"disconnect\", (reason) => {\n * // console.log(reason); prints \"io client disconnect\"\n * });\n *\n * socket.disconnect();\n *\n * @return self\n */\n disconnect() {\n if (this.connected) {\n debug(\"performing disconnect (%s)\", this.nsp);\n this.packet({ type: socket_io_parser_1.PacketType.DISCONNECT });\n }\n // remove socket from pool\n this.destroy();\n if (this.connected) {\n // fire events\n this.onclose(\"io client disconnect\");\n }\n return this;\n }\n /**\n * Alias for {@link disconnect()}.\n *\n * @return self\n */\n close() {\n return this.disconnect();\n }\n /**\n * Sets the compress flag.\n *\n * @example\n * socket.compress(false).emit(\"hello\");\n *\n * @param compress - if `true`, compresses the sending data\n * @return self\n */\n compress(compress) {\n this.flags.compress = compress;\n return this;\n }\n /**\n * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not\n * ready to send messages.\n *\n * @example\n * socket.volatile.emit(\"hello\"); // the server may or may not receive it\n *\n * @returns self\n */\n get volatile() {\n this.flags.volatile = true;\n return this;\n }\n /**\n * Sets a modifier for a subsequent event emission that the callback will be called with an error when the\n * given number of milliseconds have elapsed without an acknowledgement from the server:\n *\n * @example\n * socket.timeout(5000).emit(\"my-event\", (err) => {\n * if (err) {\n * // the server did not acknowledge the event in the given delay\n * }\n * });\n *\n * @returns self\n */\n timeout(timeout) {\n this.flags.timeout = timeout;\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback.\n *\n * @example\n * socket.onAny((event, ...args) => {\n * console.log(`got ${event}`);\n * });\n *\n * @param listener\n */\n onAny(listener) {\n this._anyListeners = this._anyListeners || [];\n this._anyListeners.push(listener);\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback. The listener is added to the beginning of the listeners array.\n *\n * @example\n * socket.prependAny((event, ...args) => {\n * console.log(`got event ${event}`);\n * });\n *\n * @param listener\n */\n prependAny(listener) {\n this._anyListeners = this._anyListeners || [];\n this._anyListeners.unshift(listener);\n return this;\n }\n /**\n * Removes the listener that will be fired when any event is emitted.\n *\n * @example\n * const catchAllListener = (event, ...args) => {\n * console.log(`got event ${event}`);\n * }\n *\n * socket.onAny(catchAllListener);\n *\n * // remove a specific listener\n * socket.offAny(catchAllListener);\n *\n * // or remove all listeners\n * socket.offAny();\n *\n * @param listener\n */\n offAny(listener) {\n if (!this._anyListeners) {\n return this;\n }\n if (listener) {\n const listeners = this._anyListeners;\n for (let i = 0; i < listeners.length; i++) {\n if (listener === listeners[i]) {\n listeners.splice(i, 1);\n return this;\n }\n }\n }\n else {\n this._anyListeners = [];\n }\n return this;\n }\n /**\n * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,\n * e.g. to remove listeners.\n */\n listenersAny() {\n return this._anyListeners || [];\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback.\n *\n * Note: acknowledgements sent to the server are not included.\n *\n * @example\n * socket.onAnyOutgoing((event, ...args) => {\n * console.log(`sent event ${event}`);\n * });\n *\n * @param listener\n */\n onAnyOutgoing(listener) {\n this._anyOutgoingListeners = this._anyOutgoingListeners || [];\n this._anyOutgoingListeners.push(listener);\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback. The listener is added to the beginning of the listeners array.\n *\n * Note: acknowledgements sent to the server are not included.\n *\n * @example\n * socket.prependAnyOutgoing((event, ...args) => {\n * console.log(`sent event ${event}`);\n * });\n *\n * @param listener\n */\n prependAnyOutgoing(listener) {\n this._anyOutgoingListeners = this._anyOutgoingListeners || [];\n this._anyOutgoingListeners.unshift(listener);\n return this;\n }\n /**\n * Removes the listener that will be fired when any event is emitted.\n *\n * @example\n * const catchAllListener = (event, ...args) => {\n * console.log(`sent event ${event}`);\n * }\n *\n * socket.onAnyOutgoing(catchAllListener);\n *\n * // remove a specific listener\n * socket.offAnyOutgoing(catchAllListener);\n *\n * // or remove all listeners\n * socket.offAnyOutgoing();\n *\n * @param [listener] - the catch-all listener (optional)\n */\n offAnyOutgoing(listener) {\n if (!this._anyOutgoingListeners) {\n return this;\n }\n if (listener) {\n const listeners = this._anyOutgoingListeners;\n for (let i = 0; i < listeners.length; i++) {\n if (listener === listeners[i]) {\n listeners.splice(i, 1);\n return this;\n }\n }\n }\n else {\n this._anyOutgoingListeners = [];\n }\n return this;\n }\n /**\n * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,\n * e.g. to remove listeners.\n */\n listenersAnyOutgoing() {\n return this._anyOutgoingListeners || [];\n }\n /**\n * Notify the listeners for each packet sent\n *\n * @param packet\n *\n * @private\n */\n notifyOutgoingListeners(packet) {\n if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) {\n const listeners = this._anyOutgoingListeners.slice();\n for (const listener of listeners) {\n listener.apply(this, packet.data);\n }\n }\n }\n}\nexports.Socket = Socket;\n\n\n//# sourceURL=webpack://sqlitecloud/./node_modules/socket.io-client/build/cjs/socket.js?");
|
|
495
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Socket = void 0;\nconst socket_io_parser_1 = __webpack_require__(/*! socket.io-parser */ \"./node_modules/socket.io-parser/build/cjs/index.js\");\nconst on_js_1 = __webpack_require__(/*! ./on.js */ \"./node_modules/socket.io-client/build/cjs/on.js\");\nconst component_emitter_1 = __webpack_require__(/*! @socket.io/component-emitter */ \"./node_modules/@socket.io/component-emitter/index.mjs\");\nconst debug_1 = __importDefault(__webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")); // debug()\nconst debug = debug_1.default(\"socket.io-client:socket\"); // debug()\n/**\n * Internal events.\n * These events can't be emitted by the user.\n */\nconst RESERVED_EVENTS = Object.freeze({\n connect: 1,\n connect_error: 1,\n disconnect: 1,\n disconnecting: 1,\n // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener\n newListener: 1,\n removeListener: 1,\n});\n/**\n * A Socket is the fundamental class for interacting with the server.\n *\n * A Socket belongs to a certain Namespace (by default /) and uses an underlying {@link Manager} to communicate.\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"connect\", () => {\n * console.log(\"connected\");\n * });\n *\n * // send an event to the server\n * socket.emit(\"foo\", \"bar\");\n *\n * socket.on(\"foobar\", () => {\n * // an event was received from the server\n * });\n *\n * // upon disconnection\n * socket.on(\"disconnect\", (reason) => {\n * console.log(`disconnected due to ${reason}`);\n * });\n */\nclass Socket extends component_emitter_1.Emitter {\n /**\n * `Socket` constructor.\n */\n constructor(io, nsp, opts) {\n super();\n /**\n * Whether the socket is currently connected to the server.\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"connect\", () => {\n * console.log(socket.connected); // true\n * });\n *\n * socket.on(\"disconnect\", () => {\n * console.log(socket.connected); // false\n * });\n */\n this.connected = false;\n /**\n * Whether the connection state was recovered after a temporary disconnection. In that case, any missed packets will\n * be transmitted by the server.\n */\n this.recovered = false;\n /**\n * Buffer for packets received before the CONNECT packet\n */\n this.receiveBuffer = [];\n /**\n * Buffer for packets that will be sent once the socket is connected\n */\n this.sendBuffer = [];\n /**\n * The queue of packets to be sent with retry in case of failure.\n *\n * Packets are sent one by one, each waiting for the server acknowledgement, in order to guarantee the delivery order.\n * @private\n */\n this._queue = [];\n /**\n * A sequence to generate the ID of the {@link QueuedPacket}.\n * @private\n */\n this._queueSeq = 0;\n this.ids = 0;\n /**\n * A map containing acknowledgement handlers.\n *\n * The `withError` attribute is used to differentiate handlers that accept an error as first argument:\n *\n * - `socket.emit(\"test\", (err, value) => { ... })` with `ackTimeout` option\n * - `socket.timeout(5000).emit(\"test\", (err, value) => { ... })`\n * - `const value = await socket.emitWithAck(\"test\")`\n *\n * From those that don't:\n *\n * - `socket.emit(\"test\", (value) => { ... });`\n *\n * In the first case, the handlers will be called with an error when:\n *\n * - the timeout is reached\n * - the socket gets disconnected\n *\n * In the second case, the handlers will be simply discarded upon disconnection, since the client will never receive\n * an acknowledgement from the server.\n *\n * @private\n */\n this.acks = {};\n this.flags = {};\n this.io = io;\n this.nsp = nsp;\n if (opts && opts.auth) {\n this.auth = opts.auth;\n }\n this._opts = Object.assign({}, opts);\n if (this.io._autoConnect)\n this.open();\n }\n /**\n * Whether the socket is currently disconnected\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"connect\", () => {\n * console.log(socket.disconnected); // false\n * });\n *\n * socket.on(\"disconnect\", () => {\n * console.log(socket.disconnected); // true\n * });\n */\n get disconnected() {\n return !this.connected;\n }\n /**\n * Subscribe to open, close and packet events\n *\n * @private\n */\n subEvents() {\n if (this.subs)\n return;\n const io = this.io;\n this.subs = [\n on_js_1.on(io, \"open\", this.onopen.bind(this)),\n on_js_1.on(io, \"packet\", this.onpacket.bind(this)),\n on_js_1.on(io, \"error\", this.onerror.bind(this)),\n on_js_1.on(io, \"close\", this.onclose.bind(this)),\n ];\n }\n /**\n * Whether the Socket will try to reconnect when its Manager connects or reconnects.\n *\n * @example\n * const socket = io();\n *\n * console.log(socket.active); // true\n *\n * socket.on(\"disconnect\", (reason) => {\n * if (reason === \"io server disconnect\") {\n * // the disconnection was initiated by the server, you need to manually reconnect\n * console.log(socket.active); // false\n * }\n * // else the socket will automatically try to reconnect\n * console.log(socket.active); // true\n * });\n */\n get active() {\n return !!this.subs;\n }\n /**\n * \"Opens\" the socket.\n *\n * @example\n * const socket = io({\n * autoConnect: false\n * });\n *\n * socket.connect();\n */\n connect() {\n if (this.connected)\n return this;\n this.subEvents();\n if (!this.io[\"_reconnecting\"])\n this.io.open(); // ensure open\n if (\"open\" === this.io._readyState)\n this.onopen();\n return this;\n }\n /**\n * Alias for {@link connect()}.\n */\n open() {\n return this.connect();\n }\n /**\n * Sends a `message` event.\n *\n * This method mimics the WebSocket.send() method.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send\n *\n * @example\n * socket.send(\"hello\");\n *\n * // this is equivalent to\n * socket.emit(\"message\", \"hello\");\n *\n * @return self\n */\n send(...args) {\n args.unshift(\"message\");\n this.emit.apply(this, args);\n return this;\n }\n /**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @example\n * socket.emit(\"hello\", \"world\");\n *\n * // all serializable datastructures are supported (no need to call JSON.stringify)\n * socket.emit(\"hello\", 1, \"2\", { 3: [\"4\"], 5: Uint8Array.from([6]) });\n *\n * // with an acknowledgement from the server\n * socket.emit(\"hello\", \"world\", (val) => {\n * // ...\n * });\n *\n * @return self\n */\n emit(ev, ...args) {\n if (RESERVED_EVENTS.hasOwnProperty(ev)) {\n throw new Error('\"' + ev.toString() + '\" is a reserved event name');\n }\n args.unshift(ev);\n if (this._opts.retries && !this.flags.fromQueue && !this.flags.volatile) {\n this._addToQueue(args);\n return this;\n }\n const packet = {\n type: socket_io_parser_1.PacketType.EVENT,\n data: args,\n };\n packet.options = {};\n packet.options.compress = this.flags.compress !== false;\n // event ack callback\n if (\"function\" === typeof args[args.length - 1]) {\n const id = this.ids++;\n debug(\"emitting packet with ack id %d\", id);\n const ack = args.pop();\n this._registerAckCallback(id, ack);\n packet.id = id;\n }\n const isTransportWritable = this.io.engine &&\n this.io.engine.transport &&\n this.io.engine.transport.writable;\n const discardPacket = this.flags.volatile && (!isTransportWritable || !this.connected);\n if (discardPacket) {\n debug(\"discard packet as the transport is not currently writable\");\n }\n else if (this.connected) {\n this.notifyOutgoingListeners(packet);\n this.packet(packet);\n }\n else {\n this.sendBuffer.push(packet);\n }\n this.flags = {};\n return this;\n }\n /**\n * @private\n */\n _registerAckCallback(id, ack) {\n var _a;\n const timeout = (_a = this.flags.timeout) !== null && _a !== void 0 ? _a : this._opts.ackTimeout;\n if (timeout === undefined) {\n this.acks[id] = ack;\n return;\n }\n // @ts-ignore\n const timer = this.io.setTimeoutFn(() => {\n delete this.acks[id];\n for (let i = 0; i < this.sendBuffer.length; i++) {\n if (this.sendBuffer[i].id === id) {\n debug(\"removing packet with ack id %d from the buffer\", id);\n this.sendBuffer.splice(i, 1);\n }\n }\n debug(\"event with ack id %d has timed out after %d ms\", id, timeout);\n ack.call(this, new Error(\"operation has timed out\"));\n }, timeout);\n const fn = (...args) => {\n // @ts-ignore\n this.io.clearTimeoutFn(timer);\n ack.apply(this, args);\n };\n fn.withError = true;\n this.acks[id] = fn;\n }\n /**\n * Emits an event and waits for an acknowledgement\n *\n * @example\n * // without timeout\n * const response = await socket.emitWithAck(\"hello\", \"world\");\n *\n * // with a specific timeout\n * try {\n * const response = await socket.timeout(1000).emitWithAck(\"hello\", \"world\");\n * } catch (err) {\n * // the server did not acknowledge the event in the given delay\n * }\n *\n * @return a Promise that will be fulfilled when the server acknowledges the event\n */\n emitWithAck(ev, ...args) {\n return new Promise((resolve, reject) => {\n const fn = (arg1, arg2) => {\n return arg1 ? reject(arg1) : resolve(arg2);\n };\n fn.withError = true;\n args.push(fn);\n this.emit(ev, ...args);\n });\n }\n /**\n * Add the packet to the queue.\n * @param args\n * @private\n */\n _addToQueue(args) {\n let ack;\n if (typeof args[args.length - 1] === \"function\") {\n ack = args.pop();\n }\n const packet = {\n id: this._queueSeq++,\n tryCount: 0,\n pending: false,\n args,\n flags: Object.assign({ fromQueue: true }, this.flags),\n };\n args.push((err, ...responseArgs) => {\n if (packet !== this._queue[0]) {\n // the packet has already been acknowledged\n return;\n }\n const hasError = err !== null;\n if (hasError) {\n if (packet.tryCount > this._opts.retries) {\n debug(\"packet [%d] is discarded after %d tries\", packet.id, packet.tryCount);\n this._queue.shift();\n if (ack) {\n ack(err);\n }\n }\n }\n else {\n debug(\"packet [%d] was successfully sent\", packet.id);\n this._queue.shift();\n if (ack) {\n ack(null, ...responseArgs);\n }\n }\n packet.pending = false;\n return this._drainQueue();\n });\n this._queue.push(packet);\n this._drainQueue();\n }\n /**\n * Send the first packet of the queue, and wait for an acknowledgement from the server.\n * @param force - whether to resend a packet that has not been acknowledged yet\n *\n * @private\n */\n _drainQueue(force = false) {\n debug(\"draining queue\");\n if (!this.connected || this._queue.length === 0) {\n return;\n }\n const packet = this._queue[0];\n if (packet.pending && !force) {\n debug(\"packet [%d] has already been sent and is waiting for an ack\", packet.id);\n return;\n }\n packet.pending = true;\n packet.tryCount++;\n debug(\"sending packet [%d] (try n°%d)\", packet.id, packet.tryCount);\n this.flags = packet.flags;\n this.emit.apply(this, packet.args);\n }\n /**\n * Sends a packet.\n *\n * @param packet\n * @private\n */\n packet(packet) {\n packet.nsp = this.nsp;\n this.io._packet(packet);\n }\n /**\n * Called upon engine `open`.\n *\n * @private\n */\n onopen() {\n debug(\"transport is open - connecting\");\n if (typeof this.auth == \"function\") {\n this.auth((data) => {\n this._sendConnectPacket(data);\n });\n }\n else {\n this._sendConnectPacket(this.auth);\n }\n }\n /**\n * Sends a CONNECT packet to initiate the Socket.IO session.\n *\n * @param data\n * @private\n */\n _sendConnectPacket(data) {\n this.packet({\n type: socket_io_parser_1.PacketType.CONNECT,\n data: this._pid\n ? Object.assign({ pid: this._pid, offset: this._lastOffset }, data)\n : data,\n });\n }\n /**\n * Called upon engine or manager `error`.\n *\n * @param err\n * @private\n */\n onerror(err) {\n if (!this.connected) {\n this.emitReserved(\"connect_error\", err);\n }\n }\n /**\n * Called upon engine `close`.\n *\n * @param reason\n * @param description\n * @private\n */\n onclose(reason, description) {\n debug(\"close (%s)\", reason);\n this.connected = false;\n delete this.id;\n this.emitReserved(\"disconnect\", reason, description);\n this._clearAcks();\n }\n /**\n * Clears the acknowledgement handlers upon disconnection, since the client will never receive an acknowledgement from\n * the server.\n *\n * @private\n */\n _clearAcks() {\n Object.keys(this.acks).forEach((id) => {\n const isBuffered = this.sendBuffer.some((packet) => String(packet.id) === id);\n if (!isBuffered) {\n // note: handlers that do not accept an error as first argument are ignored here\n const ack = this.acks[id];\n delete this.acks[id];\n if (ack.withError) {\n ack.call(this, new Error(\"socket has been disconnected\"));\n }\n }\n });\n }\n /**\n * Called with socket packet.\n *\n * @param packet\n * @private\n */\n onpacket(packet) {\n const sameNamespace = packet.nsp === this.nsp;\n if (!sameNamespace)\n return;\n switch (packet.type) {\n case socket_io_parser_1.PacketType.CONNECT:\n if (packet.data && packet.data.sid) {\n this.onconnect(packet.data.sid, packet.data.pid);\n }\n else {\n this.emitReserved(\"connect_error\", new Error(\"It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)\"));\n }\n break;\n case socket_io_parser_1.PacketType.EVENT:\n case socket_io_parser_1.PacketType.BINARY_EVENT:\n this.onevent(packet);\n break;\n case socket_io_parser_1.PacketType.ACK:\n case socket_io_parser_1.PacketType.BINARY_ACK:\n this.onack(packet);\n break;\n case socket_io_parser_1.PacketType.DISCONNECT:\n this.ondisconnect();\n break;\n case socket_io_parser_1.PacketType.CONNECT_ERROR:\n this.destroy();\n const err = new Error(packet.data.message);\n // @ts-ignore\n err.data = packet.data.data;\n this.emitReserved(\"connect_error\", err);\n break;\n }\n }\n /**\n * Called upon a server event.\n *\n * @param packet\n * @private\n */\n onevent(packet) {\n const args = packet.data || [];\n debug(\"emitting event %j\", args);\n if (null != packet.id) {\n debug(\"attaching ack callback to event\");\n args.push(this.ack(packet.id));\n }\n if (this.connected) {\n this.emitEvent(args);\n }\n else {\n this.receiveBuffer.push(Object.freeze(args));\n }\n }\n emitEvent(args) {\n if (this._anyListeners && this._anyListeners.length) {\n const listeners = this._anyListeners.slice();\n for (const listener of listeners) {\n listener.apply(this, args);\n }\n }\n super.emit.apply(this, args);\n if (this._pid && args.length && typeof args[args.length - 1] === \"string\") {\n this._lastOffset = args[args.length - 1];\n }\n }\n /**\n * Produces an ack callback to emit with an event.\n *\n * @private\n */\n ack(id) {\n const self = this;\n let sent = false;\n return function (...args) {\n // prevent double callbacks\n if (sent)\n return;\n sent = true;\n debug(\"sending ack %j\", args);\n self.packet({\n type: socket_io_parser_1.PacketType.ACK,\n id: id,\n data: args,\n });\n };\n }\n /**\n * Called upon a server acknowledgement.\n *\n * @param packet\n * @private\n */\n onack(packet) {\n const ack = this.acks[packet.id];\n if (typeof ack !== \"function\") {\n debug(\"bad ack %s\", packet.id);\n return;\n }\n delete this.acks[packet.id];\n debug(\"calling ack %s with %j\", packet.id, packet.data);\n // @ts-ignore FIXME ack is incorrectly inferred as 'never'\n if (ack.withError) {\n packet.data.unshift(null);\n }\n // @ts-ignore\n ack.apply(this, packet.data);\n }\n /**\n * Called upon server connect.\n *\n * @private\n */\n onconnect(id, pid) {\n debug(\"socket connected with id %s\", id);\n this.id = id;\n this.recovered = pid && this._pid === pid;\n this._pid = pid; // defined only if connection state recovery is enabled\n this.connected = true;\n this.emitBuffered();\n this.emitReserved(\"connect\");\n this._drainQueue(true);\n }\n /**\n * Emit buffered events (received and emitted).\n *\n * @private\n */\n emitBuffered() {\n this.receiveBuffer.forEach((args) => this.emitEvent(args));\n this.receiveBuffer = [];\n this.sendBuffer.forEach((packet) => {\n this.notifyOutgoingListeners(packet);\n this.packet(packet);\n });\n this.sendBuffer = [];\n }\n /**\n * Called upon server disconnect.\n *\n * @private\n */\n ondisconnect() {\n debug(\"server disconnect (%s)\", this.nsp);\n this.destroy();\n this.onclose(\"io server disconnect\");\n }\n /**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @private\n */\n destroy() {\n if (this.subs) {\n // clean subscriptions to avoid reconnections\n this.subs.forEach((subDestroy) => subDestroy());\n this.subs = undefined;\n }\n this.io[\"_destroy\"](this);\n }\n /**\n * Disconnects the socket manually. In that case, the socket will not try to reconnect.\n *\n * If this is the last active Socket instance of the {@link Manager}, the low-level connection will be closed.\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"disconnect\", (reason) => {\n * // console.log(reason); prints \"io client disconnect\"\n * });\n *\n * socket.disconnect();\n *\n * @return self\n */\n disconnect() {\n if (this.connected) {\n debug(\"performing disconnect (%s)\", this.nsp);\n this.packet({ type: socket_io_parser_1.PacketType.DISCONNECT });\n }\n // remove socket from pool\n this.destroy();\n if (this.connected) {\n // fire events\n this.onclose(\"io client disconnect\");\n }\n return this;\n }\n /**\n * Alias for {@link disconnect()}.\n *\n * @return self\n */\n close() {\n return this.disconnect();\n }\n /**\n * Sets the compress flag.\n *\n * @example\n * socket.compress(false).emit(\"hello\");\n *\n * @param compress - if `true`, compresses the sending data\n * @return self\n */\n compress(compress) {\n this.flags.compress = compress;\n return this;\n }\n /**\n * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not\n * ready to send messages.\n *\n * @example\n * socket.volatile.emit(\"hello\"); // the server may or may not receive it\n *\n * @returns self\n */\n get volatile() {\n this.flags.volatile = true;\n return this;\n }\n /**\n * Sets a modifier for a subsequent event emission that the callback will be called with an error when the\n * given number of milliseconds have elapsed without an acknowledgement from the server:\n *\n * @example\n * socket.timeout(5000).emit(\"my-event\", (err) => {\n * if (err) {\n * // the server did not acknowledge the event in the given delay\n * }\n * });\n *\n * @returns self\n */\n timeout(timeout) {\n this.flags.timeout = timeout;\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback.\n *\n * @example\n * socket.onAny((event, ...args) => {\n * console.log(`got ${event}`);\n * });\n *\n * @param listener\n */\n onAny(listener) {\n this._anyListeners = this._anyListeners || [];\n this._anyListeners.push(listener);\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback. The listener is added to the beginning of the listeners array.\n *\n * @example\n * socket.prependAny((event, ...args) => {\n * console.log(`got event ${event}`);\n * });\n *\n * @param listener\n */\n prependAny(listener) {\n this._anyListeners = this._anyListeners || [];\n this._anyListeners.unshift(listener);\n return this;\n }\n /**\n * Removes the listener that will be fired when any event is emitted.\n *\n * @example\n * const catchAllListener = (event, ...args) => {\n * console.log(`got event ${event}`);\n * }\n *\n * socket.onAny(catchAllListener);\n *\n * // remove a specific listener\n * socket.offAny(catchAllListener);\n *\n * // or remove all listeners\n * socket.offAny();\n *\n * @param listener\n */\n offAny(listener) {\n if (!this._anyListeners) {\n return this;\n }\n if (listener) {\n const listeners = this._anyListeners;\n for (let i = 0; i < listeners.length; i++) {\n if (listener === listeners[i]) {\n listeners.splice(i, 1);\n return this;\n }\n }\n }\n else {\n this._anyListeners = [];\n }\n return this;\n }\n /**\n * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,\n * e.g. to remove listeners.\n */\n listenersAny() {\n return this._anyListeners || [];\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback.\n *\n * Note: acknowledgements sent to the server are not included.\n *\n * @example\n * socket.onAnyOutgoing((event, ...args) => {\n * console.log(`sent event ${event}`);\n * });\n *\n * @param listener\n */\n onAnyOutgoing(listener) {\n this._anyOutgoingListeners = this._anyOutgoingListeners || [];\n this._anyOutgoingListeners.push(listener);\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback. The listener is added to the beginning of the listeners array.\n *\n * Note: acknowledgements sent to the server are not included.\n *\n * @example\n * socket.prependAnyOutgoing((event, ...args) => {\n * console.log(`sent event ${event}`);\n * });\n *\n * @param listener\n */\n prependAnyOutgoing(listener) {\n this._anyOutgoingListeners = this._anyOutgoingListeners || [];\n this._anyOutgoingListeners.unshift(listener);\n return this;\n }\n /**\n * Removes the listener that will be fired when any event is emitted.\n *\n * @example\n * const catchAllListener = (event, ...args) => {\n * console.log(`sent event ${event}`);\n * }\n *\n * socket.onAnyOutgoing(catchAllListener);\n *\n * // remove a specific listener\n * socket.offAnyOutgoing(catchAllListener);\n *\n * // or remove all listeners\n * socket.offAnyOutgoing();\n *\n * @param [listener] - the catch-all listener (optional)\n */\n offAnyOutgoing(listener) {\n if (!this._anyOutgoingListeners) {\n return this;\n }\n if (listener) {\n const listeners = this._anyOutgoingListeners;\n for (let i = 0; i < listeners.length; i++) {\n if (listener === listeners[i]) {\n listeners.splice(i, 1);\n return this;\n }\n }\n }\n else {\n this._anyOutgoingListeners = [];\n }\n return this;\n }\n /**\n * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,\n * e.g. to remove listeners.\n */\n listenersAnyOutgoing() {\n return this._anyOutgoingListeners || [];\n }\n /**\n * Notify the listeners for each packet sent\n *\n * @param packet\n *\n * @private\n */\n notifyOutgoingListeners(packet) {\n if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) {\n const listeners = this._anyOutgoingListeners.slice();\n for (const listener of listeners) {\n listener.apply(this, packet.data);\n }\n }\n }\n}\nexports.Socket = Socket;\n\n\n//# sourceURL=webpack://sqlitecloud/./node_modules/socket.io-client/build/cjs/socket.js?");
|
|
496
496
|
|
|
497
497
|
/***/ }),
|
|
498
498
|
|