@sqlitecloud/drivers 1.0.417 → 1.0.422
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 +2 -2
- package/lib/drivers/connection-tls.d.ts +1 -1
- package/lib/drivers/connection-tls.js +10 -2
- package/lib/drivers/connection-ws.d.ts +1 -1
- package/lib/drivers/connection-ws.js +19 -8
- package/lib/drivers/database.d.ts +12 -9
- package/lib/drivers/database.js +115 -142
- package/lib/drivers/pubsub.js +2 -2
- package/lib/sqlitecloud.drivers.dev.js +4 -4
- package/lib/sqlitecloud.drivers.js +1 -1
- package/package.json +2 -2
|
@@ -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 () {\n var ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n };\n return function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n };\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\");\n// explicitly importing buffer library to allow cross-platform support by replacing it\nconst buffer_1 = __webpack_require__(/*! buffer */ \"./node_modules/buffer/index.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_1.Buffer.alloc(0);\n this.startedOn = new Date();\n this.pendingChunks = [];\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 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 // tls.connect in the react-native-tcp-socket library is tls.connectTLS\n let connector = tls.connect;\n // @ts-ignore\n if (typeof tls.connectTLS !== 'undefined') {\n // @ts-ignore\n connector = tls.connectTLS;\n }\n this.socket = connector(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 if (typeof commands === 'string') {\n commands = { query: commands };\n }\n // reset buffer and rowset chunks, define response callback\n this.buffer = buffer_1.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, _g;\n try {\n // append data to buffer as it arrives\n if (data.length && data.length > 0) {\n // console.debug(`processCommandsData - received ${data.length} bytes`)\n this.buffer = buffer_1.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} (${bufferString.length} bytes, ${elapsedMs}ms)`);\n }\n // need to decompress this buffer before decoding?\n if (dataType === protocol_1.CMD_COMPRESSED) {\n const decompressResults = (0, protocol_1.decompressBuffer)(this.buffer);\n if (decompressResults.dataType === protocol_1.CMD_ROWSET_CHUNK) {\n this.pendingChunks.push(decompressResults.buffer);\n this.buffer = decompressResults.remainingBuffer;\n this.processCommandsData(buffer_1.Buffer.alloc(0));\n return;\n }\n else {\n const { data } = (0, protocol_1.popData)(decompressResults.buffer);\n (_c = this.processCommandsFinish) === null || _c === void 0 ? void 0 : _c.call(this, null, data);\n }\n }\n else {\n if (dataType !== protocol_1.CMD_ROWSET_CHUNK) {\n const { data } = (0, protocol_1.popData)(this.buffer);\n (_d = this.processCommandsFinish) === null || _d === void 0 ? void 0 : _d.call(this, null, data);\n }\n else {\n const completeChunk = (0, protocol_1.bufferEndsWith)(this.buffer, protocol_1.ROWSET_CHUNKS_END);\n if (completeChunk) {\n const parsedData = (0, protocol_1.parseRowsetChunks)([...this.pendingChunks, this.buffer]);\n (_e = this.processCommandsFinish) === null || _e === void 0 ? void 0 : _e.call(this, null, parsedData);\n }\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 (_f = this.processCommandsFinish) === null || _f === void 0 ? void 0 : _f.call(this, null, data);\n }\n }\n }\n catch (error) {\n console.error(`processCommandsData - error: ${error}`);\n console.assert(error instanceof Error, 'An error occoured while processing data');\n if (error instanceof Error) {\n (_g = this.processCommandsFinish) === null || _g === void 0 ? void 0 : _g.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 }\n this.buffer = buffer_1.Buffer.alloc(0);\n this.pendingChunks = [];\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 () {\n var ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n };\n return function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n };\n})();\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudTlsConnection = void 0;\nconst connection_1 = __webpack_require__(/*! ./connection */ \"./lib/drivers/connection.js\");\nconst protocol_1 = __webpack_require__(/*! ./protocol */ \"./lib/drivers/protocol.js\");\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\n// explicitly importing buffer library to allow cross-platform support by replacing it\nconst buffer_1 = __webpack_require__(/*! buffer */ \"./node_modules/buffer/index.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_1.Buffer.alloc(0);\n this.startedOn = new Date();\n this.pendingChunks = [];\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 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 // tls.connect in the react-native-tcp-socket library is tls.connectTLS\n let connector = tls.connect;\n // @ts-ignore\n if (typeof tls.connectTLS !== 'undefined') {\n // @ts-ignore\n connector = tls.connectTLS;\n }\n this.socket = connector(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.setKeepAlive(true);\n // disable Nagle algorithm because we want our writes to be sent ASAP\n // https://brooker.co.za/blog/2024/05/09/nagle.html\n this.socket.setNoDelay(true);\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 this.socket.on('timeout', () => {\n this.close();\n this.processCommandsFinish(new types_1.SQLiteCloudError('Connection ened due to timeout', { errorCode: 'ERR_CONNECTION_TIMEOUT' }));\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 if (typeof commands === 'string') {\n commands = { query: commands };\n }\n // reset buffer and rowset chunks, define response callback\n this.buffer = buffer_1.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, _g;\n try {\n // append data to buffer as it arrives\n if (data.length && data.length > 0) {\n // console.debug(`processCommandsData - received ${data.length} bytes`)\n this.buffer = buffer_1.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} (${bufferString.length} bytes, ${elapsedMs}ms)`);\n }\n // need to decompress this buffer before decoding?\n if (dataType === protocol_1.CMD_COMPRESSED) {\n const decompressResults = (0, protocol_1.decompressBuffer)(this.buffer);\n if (decompressResults.dataType === protocol_1.CMD_ROWSET_CHUNK) {\n this.pendingChunks.push(decompressResults.buffer);\n this.buffer = decompressResults.remainingBuffer;\n this.processCommandsData(buffer_1.Buffer.alloc(0));\n return;\n }\n else {\n const { data } = (0, protocol_1.popData)(decompressResults.buffer);\n (_c = this.processCommandsFinish) === null || _c === void 0 ? void 0 : _c.call(this, null, data);\n }\n }\n else {\n if (dataType !== protocol_1.CMD_ROWSET_CHUNK) {\n const { data } = (0, protocol_1.popData)(this.buffer);\n (_d = this.processCommandsFinish) === null || _d === void 0 ? void 0 : _d.call(this, null, data);\n }\n else {\n const completeChunk = (0, protocol_1.bufferEndsWith)(this.buffer, protocol_1.ROWSET_CHUNKS_END);\n if (completeChunk) {\n const parsedData = (0, protocol_1.parseRowsetChunks)([...this.pendingChunks, this.buffer]);\n (_e = this.processCommandsFinish) === null || _e === void 0 ? void 0 : _e.call(this, null, parsedData);\n }\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 (_f = this.processCommandsFinish) === null || _f === void 0 ? void 0 : _f.call(this, null, data);\n }\n }\n }\n catch (error) {\n console.error(`processCommandsData - error: ${error}`);\n console.assert(error instanceof Error, 'An error occoured while processing data');\n if (error instanceof Error) {\n (_g = this.processCommandsFinish) === null || _g === void 0 ? void 0 : _g.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 }\n this.buffer = buffer_1.Buffer.alloc(0);\n this.pendingChunks = [];\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
|
|
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 socket_io_client_1 = __webpack_require__(/*! socket.io-client */ \"./node_modules/socket.io-client/build/cjs/index.js\");\nconst connection_1 = __webpack_require__(/*! ./connection */ \"./lib/drivers/connection.js\");\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.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 var _a;\n return !!(this.socket && ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected));\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 this.socket.on('connect', () => {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n });\n this.socket.on('disconnect', (reason) => {\n this.close();\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Disconnected', { errorCode: 'ERR_CONNECTION_ENDED', cause: reason }));\n });\n this.socket.on('error', (error) => {\n this.close();\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Connection error', { errorCode: 'ERR_CONNECTION_ERROR', cause: error }));\n });\n }\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 if (typeof commands === 'string') {\n commands = { query: commands };\n }\n this.socket.emit('GET /v2/weblite/sql', { sql: commands.query, bind: commands.parameters, 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 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, _b;\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.removeAllListeners();\n (_b = this.socket) === null || _b === void 0 ? void 0 : _b.close();\n this.socket = undefined;\n }\n this.operations.clear();\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
|
|
|
@@ -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 () {\n var ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n };\n return function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n };\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;\n// Trying as much as possible to be a drop-in replacement for SQLite3 API\n// https://github.com/TryGhost/node-sqlite3/wiki/API\n// https://github.com/TryGhost/node-sqlite3\n// https://github.com/TryGhost/node-sqlite3/blob/master/lib/sqlite3.d.ts\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst pubsub_1 = __webpack_require__(/*! ./pubsub */ \"./lib/drivers/pubsub.js\");\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst statement_1 = __webpack_require__(/*! ./statement */ \"./lib/drivers/statement.js\");\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __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_1.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], // ROWID (sqlite3_last_insert_rowid)\n changes: results[3], // CHANGES(sqlite3_changes)\n totalChanges: results[4], // TOTAL_CHANGES (sqlite3_total_changes)\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 command = { query: sql, parameters: args };\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(command, (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 command = { query: sql, parameters: args };\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(command, (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 command = { query: sql, parameters: args };\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(command, (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 command = { query: sql, parameters: args };\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(command, (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 return new statement_1.Statement(this, sql, ...params);\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 commands = { query: '' };\n // sql is a TemplateStringsArray, the 'raw' property is specific to TemplateStringsArray\n if (Array.isArray(sql) && 'raw' in sql) {\n let query = '';\n sql.forEach((string, i) => {\n // TemplateStringsArray splits the string before each variable\n // used in the template. Add the question mark\n // to the end of the string for the number of used variables.\n query += string + (i < values.length ? '?' : '');\n });\n commands = { query, parameters: values };\n }\n else if (typeof sql === 'string') {\n commands = { query: sql, parameters: values };\n }\n else if (typeof sql === 'object') {\n commands = sql;\n }\n else {\n throw new Error('Invalid sql');\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(commands, (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 /**\n * Returns true if the database connection is open.\n */\n isConnected() {\n var _a;\n return ((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0 && this.connections[0].connected;\n }\n /**\n * PubSub class provides a Pub/Sub real-time updates and notifications system to\n * allow multiple applications to communicate with each other asynchronously.\n * It allows applications to subscribe to tables and receive notifications whenever\n * data changes in the database table. It also enables sending messages to anyone\n * subscribed to a specific channel.\n * @returns {PubSub} A PubSub object\n */\n getPubSub() {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n this.getConnection((error, connection) => {\n if (error || !connection) {\n reject(error);\n }\n else {\n resolve(new pubsub_1.PubSub(connection));\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 () {\n var ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n };\n return function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n };\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;\n// Trying as much as possible to be a drop-in replacement for SQLite3 API\n// https://github.com/TryGhost/node-sqlite3/wiki/API\n// https://github.com/TryGhost/node-sqlite3\n// https://github.com/TryGhost/node-sqlite3/blob/master/lib/sqlite3.d.ts\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst pubsub_1 = __webpack_require__(/*! ./pubsub */ \"./lib/drivers/pubsub.js\");\nconst queue_1 = __webpack_require__(/*! ./queue */ \"./lib/drivers/queue.js\");\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst statement_1 = __webpack_require__(/*! ./statement */ \"./lib/drivers/statement.js\");\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __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 /** Used to syncronize opening of connection and commands */\n this.operations = new queue_1.OperationsQueue();\n this.config = typeof config === 'string' ? { connectionstring: config } : config;\n this.connection = null;\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 the connection to the database automatically\n this.createConnection(error => {\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 createConnection(callback) {\n var _a, _b;\n // connect using websocket if tls is not supported or if explicitly requested\n const useWebsocket = utilities_1.isBrowser || ((_a = this.config) === null || _a === void 0 ? void 0 : _a.usewebsocket) || ((_b = this.config) === null || _b === void 0 ? void 0 : _b.gatewayurl);\n if (useWebsocket) {\n // socket.io transport works in both node.js and browser environments and connects via SQLite Cloud Gateway\n this.operations.enqueue(done => {\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-ws */ \"./lib/drivers/connection-ws.js\"))).then(module => {\n this.connection = new module.default(this.config, (error) => {\n if (error) {\n this.handleError(error, callback);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n this.emitEvent('open');\n }\n done(error);\n });\n })\n .catch(error => {\n this.handleError(error, callback);\n done(error);\n });\n });\n }\n else {\n this.operations.enqueue(done => {\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-tls */ \"./lib/drivers/connection-tls.js\"))).then(module => {\n this.connection = new module.default(this.config, (error) => {\n if (error) {\n this.handleError(error, callback);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n this.emitEvent('open');\n }\n done(error);\n });\n })\n .catch(error => {\n this.handleError(error, callback);\n done(error);\n });\n });\n }\n }\n enqueueCommand(command, callback) {\n this.operations.enqueue(done => {\n let error = null;\n // we don't wont to silently open a new connection after a disconnession\n if (this.connection && this.connection.connected) {\n this.connection.sendCommands(command, callback);\n }\n else {\n error = new types_1.SQLiteCloudError('Connection unavailable. Maybe it got disconnected?', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' });\n this.handleError(error, callback);\n }\n done(error);\n });\n }\n /** Handles an error by closing the connection, calling the callback and/or emitting an error event */\n handleError(error, callback) {\n var _a;\n // an errored connection is thrown out\n (_a = this.connection) === null || _a === void 0 ? void 0 : _a.close();\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], // ROWID (sqlite3_last_insert_rowid)\n changes: results[3], // CHANGES(sqlite3_changes)\n totalChanges: results[4], // TOTAL_CHANGES (sqlite3_total_changes)\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 var _a;\n this.config.verbose = true;\n (_a = this.connection) === null || _a === void 0 ? void 0 : _a.verbose();\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 command = { query: sql, parameters: args };\n this.enqueueCommand(command, (error, results) => {\n if (error) {\n this.handleError(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 return this;\n }\n get(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const command = { query: sql, parameters: args };\n this.enqueueCommand(command, (error, results) => {\n if (error) {\n this.handleError(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 return this;\n }\n all(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const command = { query: sql, parameters: args };\n this.enqueueCommand(command, (error, results) => {\n if (error) {\n this.handleError(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 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 command = { query: sql, parameters: args };\n this.enqueueCommand(command, (error, rowset) => {\n if (error) {\n this.handleError(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 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 return new statement_1.Statement(this, sql, ...params);\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.enqueueCommand(sql, (error, results) => {\n if (error) {\n this.handleError(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 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 this.operations.clear();\n (_a = this.connection) === null || _a === void 0 ? void 0 : _a.close();\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 commands = { query: '' };\n // sql is a TemplateStringsArray, the 'raw' property is specific to TemplateStringsArray\n if (Array.isArray(sql) && 'raw' in sql) {\n let query = '';\n sql.forEach((string, i) => {\n // TemplateStringsArray splits the string before each variable\n // used in the template. Add the question mark\n // to the end of the string for the number of used variables.\n query += string + (i < values.length ? '?' : '');\n });\n commands = { query, parameters: values };\n }\n else if (typeof sql === 'string') {\n commands = { query: sql, parameters: values };\n }\n else if (typeof sql === 'object') {\n commands = sql;\n }\n else {\n throw new Error('Invalid sql');\n }\n return new Promise((resolve, reject) => {\n this.enqueueCommand(commands, (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 * Returns true if the database connection is open.\n */\n isConnected() {\n return this.connection != null && this.connection.connected;\n }\n /**\n * PubSub class provides a Pub/Sub real-time updates and notifications system to\n * allow multiple applications to communicate with each other asynchronously.\n * It allows applications to subscribe to tables and receive notifications whenever\n * data changes in the database table. It also enables sending messages to anyone\n * subscribed to a specific channel.\n * @returns {PubSub} A PubSub object\n */\n getPubSub() {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n this.operations.enqueue(done => {\n let error = null;\n try {\n if (!this.connection) {\n error = new types_1.SQLiteCloudError('Connection not established', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' });\n reject(error);\n }\n else {\n resolve(new pubsub_1.PubSub(this.connection));\n }\n }\n finally {\n done(error);\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
|
|
|
@@ -81,7 +81,7 @@ eval("\n//\n// protocol.ts - low level protocol handling for SQLiteCloud transpo
|
|
|
81
81
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
82
82
|
|
|
83
83
|
"use strict";
|
|
84
|
-
eval("\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.PubSub = exports.PUBSUB_ENTITY_TYPE = void 0;\nconst connection_tls_1 = __importDefault(__webpack_require__(/*! ./connection-tls */ \"./lib/drivers/connection-tls.js\"));\nvar PUBSUB_ENTITY_TYPE;\n(function (PUBSUB_ENTITY_TYPE) {\n PUBSUB_ENTITY_TYPE[\"TABLE\"] = \"TABLE\";\n PUBSUB_ENTITY_TYPE[\"CHANNEL\"] = \"CHANNEL\";\n})(PUBSUB_ENTITY_TYPE || (exports.PUBSUB_ENTITY_TYPE = PUBSUB_ENTITY_TYPE = {}));\n/**\n * Pub/Sub class to receive changes on database tables or to send messages to channels.\n */\nclass PubSub {\n constructor(connection) {\n this.connection = connection;\n this.connectionPubSub = new connection_tls_1.default(connection.getConfig());\n }\n /**\n * Listen for a table or channel and start to receive messages to the provided callback.\n * @param entityType One of TABLE or CHANNEL'\n * @param entityName Name of the table or the channel\n * @param callback Callback to be called when a message is received\n * @param data Extra data to be passed to the callback\n */\n listen(entityType, entityName, callback, data) {\n return __awaiter(this, void 0, void 0, function* () {\n const entity = entityType === 'TABLE' ? 'TABLE ' : '';\n const authCommand = yield this.connection.sql(`LISTEN ${entity}${entityName};`);\n return new Promise((resolve, reject) => {\n this.connectionPubSub.sendCommands(authCommand, (error, results) => {\n if (error) {\n callback.call(this, error, null, data);\n reject(error);\n }\n else {\n // skip results from pubSub auth command\n if (results !== 'OK') {\n callback.call(this, null, results, data);\n }\n resolve(results);\n }\n });\n });\n });\n }\n /**\n * Stop receive messages from a table or channel.\n * @param entityType One of TABLE or CHANNEL\n * @param entityName Name of the table or the channel\n */\n unlisten(entityType, entityName) {\n return __awaiter(this, void 0, void 0, function* () {\n const subject = entityType === 'TABLE' ? 'TABLE ' : '';\n return this.connection.sql(`UNLISTEN ${subject}?;`, entityName);\n });\n }\n /**\n * Create a channel to send messages to.\n * @param name Channel name\n * @param failIfExists Raise an error if the channel already exists\n */\n createChannel(name_1) {\n return __awaiter(this, arguments, void 0, function* (name, failIfExists = true) {\n let notExistsCommand = '';\n if (!failIfExists) {\n notExistsCommand = ' IF NOT EXISTS';\n }\n return this.connection.sql(`CREATE CHANNEL ?${notExistsCommand};`, name);\n });\n }\n /**\n * Deletes a Pub/Sub channel.\n * @param name Channel name\n */\n removeChannel(name) {\n return __awaiter(this, void 0, void 0, function* () {\n return this.connection.sql(
|
|
84
|
+
eval("\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.PubSub = exports.PUBSUB_ENTITY_TYPE = void 0;\nconst connection_tls_1 = __importDefault(__webpack_require__(/*! ./connection-tls */ \"./lib/drivers/connection-tls.js\"));\nvar PUBSUB_ENTITY_TYPE;\n(function (PUBSUB_ENTITY_TYPE) {\n PUBSUB_ENTITY_TYPE[\"TABLE\"] = \"TABLE\";\n PUBSUB_ENTITY_TYPE[\"CHANNEL\"] = \"CHANNEL\";\n})(PUBSUB_ENTITY_TYPE || (exports.PUBSUB_ENTITY_TYPE = PUBSUB_ENTITY_TYPE = {}));\n/**\n * Pub/Sub class to receive changes on database tables or to send messages to channels.\n */\nclass PubSub {\n constructor(connection) {\n this.connection = connection;\n this.connectionPubSub = new connection_tls_1.default(connection.getConfig());\n }\n /**\n * Listen for a table or channel and start to receive messages to the provided callback.\n * @param entityType One of TABLE or CHANNEL'\n * @param entityName Name of the table or the channel\n * @param callback Callback to be called when a message is received\n * @param data Extra data to be passed to the callback\n */\n listen(entityType, entityName, callback, data) {\n return __awaiter(this, void 0, void 0, function* () {\n const entity = entityType === 'TABLE' ? 'TABLE ' : '';\n const authCommand = yield this.connection.sql(`LISTEN ${entity}${entityName};`);\n return new Promise((resolve, reject) => {\n this.connectionPubSub.sendCommands(authCommand, (error, results) => {\n if (error) {\n callback.call(this, error, null, data);\n reject(error);\n }\n else {\n // skip results from pubSub auth command\n if (results !== 'OK') {\n callback.call(this, null, results, data);\n }\n resolve(results);\n }\n });\n });\n });\n }\n /**\n * Stop receive messages from a table or channel.\n * @param entityType One of TABLE or CHANNEL\n * @param entityName Name of the table or the channel\n */\n unlisten(entityType, entityName) {\n return __awaiter(this, void 0, void 0, function* () {\n const subject = entityType === 'TABLE' ? 'TABLE ' : '';\n return this.connection.sql(`UNLISTEN ${subject}?;`, entityName);\n });\n }\n /**\n * Create a channel to send messages to.\n * @param name Channel name\n * @param failIfExists Raise an error if the channel already exists\n */\n createChannel(name_1) {\n return __awaiter(this, arguments, void 0, function* (name, failIfExists = true) {\n let notExistsCommand = '';\n if (!failIfExists) {\n notExistsCommand = ' IF NOT EXISTS';\n }\n return this.connection.sql(`CREATE CHANNEL ?${notExistsCommand};`, name);\n });\n }\n /**\n * Deletes a Pub/Sub channel.\n * @param name Channel name\n */\n removeChannel(name) {\n return __awaiter(this, void 0, void 0, function* () {\n return this.connection.sql('REMOVE CHANNEL ?;', name);\n });\n }\n /**\n * Send a message to the channel.\n */\n notifyChannel(channelName, message) {\n return this.connection.sql('NOTIFY ? ?;', channelName, message);\n }\n /**\n * Ask the server to close the connection to the database and\n * to keep only open the Pub/Sub connection.\n * Only interaction with Pub/Sub commands will be allowed.\n */\n setPubSubOnly() {\n return new Promise((resolve, reject) => {\n this.connection.sendCommands('PUBSUB ONLY;', (error, results) => {\n if (error) {\n reject(error);\n }\n else {\n this.connection.close();\n resolve(results);\n }\n });\n });\n }\n /** True if Pub/Sub connection is open. */\n connected() {\n return this.connectionPubSub.connected;\n }\n /** Close Pub/Sub connection. */\n close() {\n this.connectionPubSub.close();\n }\n}\nexports.PubSub = PubSub;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/pubsub.js?");
|
|
85
85
|
|
|
86
86
|
/***/ }),
|
|
87
87
|
|