hide-a-bed 5.0.2 → 5.0.4
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/cjs/impl/bulk.cjs +267 -0
- package/cjs/impl/changes.cjs +67 -0
- package/cjs/impl/crud.cjs +121 -0
- package/cjs/impl/errors.cjs +75 -0
- package/cjs/impl/logger.cjs +70 -0
- package/cjs/impl/patch.cjs +95 -0
- package/cjs/impl/query.cjs +116 -0
- package/cjs/impl/queryBuilder.cjs +99 -0
- package/cjs/impl/retry.cjs +54 -0
- package/cjs/impl/stream.cjs +121 -0
- package/cjs/impl/sugar/lock.cjs +81 -0
- package/cjs/impl/sugar/watch.cjs +159 -0
- package/cjs/impl/trackedEmitter.cjs +54 -0
- package/cjs/impl/transactionErrors.cjs +70 -0
- package/cjs/index.cjs +115 -0
- package/cjs/integration/changes.cjs +76 -0
- package/cjs/integration/disconnect-watch.cjs +52 -0
- package/cjs/integration/watch.cjs +59 -0
- package/cjs/schema/bind.cjs +51 -0
- package/cjs/schema/bulk.cjs +88 -0
- package/cjs/schema/changes.cjs +68 -0
- package/cjs/schema/config.cjs +48 -0
- package/cjs/schema/crud.cjs +77 -0
- package/cjs/schema/patch.cjs +53 -0
- package/cjs/schema/query.cjs +62 -0
- package/cjs/schema/stream.cjs +42 -0
- package/cjs/schema/sugar/lock.cjs +59 -0
- package/cjs/schema/sugar/watch.cjs +42 -0
- package/impl/bulk.d.mts +11 -0
- package/impl/bulk.d.mts.map +1 -0
- package/impl/bulk.mjs +1 -1
- package/impl/changes.d.mts +12 -0
- package/impl/changes.d.mts.map +1 -0
- package/impl/crud.d.mts +7 -0
- package/impl/crud.d.mts.map +1 -0
- package/impl/errors.d.mts +43 -0
- package/impl/errors.d.mts.map +1 -0
- package/impl/logger.d.mts +32 -0
- package/impl/logger.d.mts.map +1 -0
- package/impl/patch.d.mts +6 -0
- package/impl/patch.d.mts.map +1 -0
- package/impl/query.d.mts +195 -0
- package/impl/query.d.mts.map +1 -0
- package/impl/query.mjs +1 -1
- package/impl/queryBuilder.d.mts +94 -0
- package/impl/queryBuilder.d.mts.map +1 -0
- package/impl/retry.d.mts +2 -0
- package/impl/retry.d.mts.map +1 -0
- package/impl/stream.d.mts +3 -0
- package/impl/stream.d.mts.map +1 -0
- package/impl/sugar/lock.d.mts +5 -0
- package/impl/sugar/lock.d.mts.map +1 -0
- package/impl/sugar/watch.d.mts +34 -0
- package/impl/sugar/watch.d.mts.map +1 -0
- package/impl/trackedEmitter.d.mts +8 -0
- package/impl/trackedEmitter.d.mts.map +1 -0
- package/impl/transactionErrors.d.mts +57 -0
- package/impl/transactionErrors.d.mts.map +1 -0
- package/index.d.mts +74 -0
- package/index.d.mts.map +1 -0
- package/package.json +2 -2
- package/schema/bind.d.mts +922 -0
- package/schema/bind.d.mts.map +1 -0
- package/schema/bulk.d.mts +910 -0
- package/schema/bulk.d.mts.map +1 -0
- package/schema/changes.d.mts +191 -0
- package/schema/changes.d.mts.map +1 -0
- package/schema/config.d.mts +79 -0
- package/schema/config.d.mts.map +1 -0
- package/schema/crud.d.mts +491 -0
- package/schema/crud.d.mts.map +1 -0
- package/schema/patch.d.mts +255 -0
- package/schema/patch.d.mts.map +1 -0
- package/schema/query.d.mts +406 -0
- package/schema/query.d.mts.map +1 -0
- package/schema/stream.d.mts +211 -0
- package/schema/stream.d.mts.map +1 -0
- package/schema/sugar/lock.d.mts +238 -0
- package/schema/sugar/lock.d.mts.map +1 -0
- package/schema/sugar/watch.d.mts +127 -0
- package/schema/sugar/watch.d.mts.map +1 -0
- package/log.txt +0 -84
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var patch_exports = {};
|
|
20
|
+
__export(patch_exports, {
|
|
21
|
+
patch: () => patch,
|
|
22
|
+
patchDangerously: () => patchDangerously,
|
|
23
|
+
sleep: () => sleep
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(patch_exports);
|
|
26
|
+
var import_crud = require("./crud.cjs");
|
|
27
|
+
var import_patch = require("../schema/patch.cjs");
|
|
28
|
+
var import_logger = require("./logger.cjs");
|
|
29
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
30
|
+
const patch = import_patch.Patch.implement(async (config, id, properties) => {
|
|
31
|
+
const logger = (0, import_logger.createLogger)(config);
|
|
32
|
+
logger.info(`Starting patch operation for document ${id}`);
|
|
33
|
+
logger.debug("Patch properties:", properties);
|
|
34
|
+
const doc = await (0, import_crud.get)(config, id);
|
|
35
|
+
if (doc._rev !== properties._rev) {
|
|
36
|
+
const result2 = {};
|
|
37
|
+
result2.ok = false;
|
|
38
|
+
result2.error = "conflict";
|
|
39
|
+
result2.statusCode = 409;
|
|
40
|
+
return result2;
|
|
41
|
+
}
|
|
42
|
+
const updatedDoc = { ...doc, ...properties };
|
|
43
|
+
logger.debug("Merged document:", updatedDoc);
|
|
44
|
+
const result = await (0, import_crud.put)(config, updatedDoc);
|
|
45
|
+
logger.info(`Successfully patched document ${id}, rev: ${result.rev}`);
|
|
46
|
+
return result;
|
|
47
|
+
});
|
|
48
|
+
const patchDangerously = import_patch.PatchDangerously.implement(async (config, id, properties) => {
|
|
49
|
+
const logger = (0, import_logger.createLogger)(config);
|
|
50
|
+
const maxRetries = config.maxRetries || 5;
|
|
51
|
+
let delay = config.initialDelay || 1e3;
|
|
52
|
+
let attempts = 0;
|
|
53
|
+
logger.info(`Starting patch operation for document ${id}`);
|
|
54
|
+
logger.debug("Patch properties:", properties);
|
|
55
|
+
while (attempts <= maxRetries) {
|
|
56
|
+
logger.debug(`Attempt ${attempts + 1} of ${maxRetries + 1}`);
|
|
57
|
+
try {
|
|
58
|
+
const doc = await (0, import_crud.get)(config, id);
|
|
59
|
+
if (!doc) {
|
|
60
|
+
logger.warn(`Document ${id} not found`);
|
|
61
|
+
return { ok: false, statusCode: 404, error: "not_found" };
|
|
62
|
+
}
|
|
63
|
+
const updatedDoc = { ...doc, ...properties };
|
|
64
|
+
logger.debug("Merged document:", updatedDoc);
|
|
65
|
+
const result = await (0, import_crud.put)(config, updatedDoc);
|
|
66
|
+
if (result.ok) {
|
|
67
|
+
logger.info(`Successfully patched document ${id}, rev: ${result.rev}`);
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
attempts++;
|
|
71
|
+
if (attempts > maxRetries) {
|
|
72
|
+
logger.error(`Failed to patch ${id} after ${maxRetries} attempts`);
|
|
73
|
+
throw new Error(`Failed to patch after ${maxRetries} attempts`);
|
|
74
|
+
}
|
|
75
|
+
logger.warn(`Conflict detected for ${id}, retrying (attempt ${attempts})`);
|
|
76
|
+
await sleep(delay);
|
|
77
|
+
delay *= config.backoffFactor;
|
|
78
|
+
logger.debug(`Next retry delay: ${delay}ms`);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
if (err.message === "not_found") {
|
|
81
|
+
logger.warn(`Document ${id} not found during patch operation`);
|
|
82
|
+
return { ok: false, statusCode: 404, error: "not_found" };
|
|
83
|
+
}
|
|
84
|
+
attempts++;
|
|
85
|
+
if (attempts > maxRetries) {
|
|
86
|
+
const error = `Failed to patch after ${maxRetries} attempts: ${err.message}`;
|
|
87
|
+
logger.error(error);
|
|
88
|
+
return { ok: false, statusCode: 500, error };
|
|
89
|
+
}
|
|
90
|
+
logger.warn(`Error during patch attempt ${attempts}: ${err.message}`);
|
|
91
|
+
await sleep(delay);
|
|
92
|
+
logger.debug(`Retrying after ${delay}ms`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var query_exports = {};
|
|
30
|
+
__export(query_exports, {
|
|
31
|
+
query: () => query,
|
|
32
|
+
queryString: () => queryString
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(query_exports);
|
|
35
|
+
var import_zod = require("zod");
|
|
36
|
+
var import_needle = __toESM(require("needle"), 1);
|
|
37
|
+
var import_query = require("../schema/query.cjs");
|
|
38
|
+
var import_errors = require("./errors.cjs");
|
|
39
|
+
var import_logger = require("./logger.cjs");
|
|
40
|
+
var import_lodash = __toESM(require("lodash"), 1);
|
|
41
|
+
const { includes } = import_lodash.default;
|
|
42
|
+
const query = import_query.SimpleViewQuery.implement(async (config, view, options = {}) => {
|
|
43
|
+
const logger = (0, import_logger.createLogger)(config);
|
|
44
|
+
logger.info(`Starting view query: ${view}`);
|
|
45
|
+
logger.debug("Query options:", options);
|
|
46
|
+
let qs = queryString(options, ["key", "startkey", "endkey", "reduce", "group", "group_level", "stale", "limit"]);
|
|
47
|
+
let method = "GET";
|
|
48
|
+
let payload = null;
|
|
49
|
+
const opts = {
|
|
50
|
+
json: true,
|
|
51
|
+
headers: {
|
|
52
|
+
"Content-Type": "application/json"
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
if (typeof options.keys !== "undefined") {
|
|
56
|
+
const MAX_URL_LENGTH = 2e3;
|
|
57
|
+
const _options = JSON.parse(JSON.stringify(options));
|
|
58
|
+
delete _options.keys;
|
|
59
|
+
qs = queryString(_options, ["key", "startkey", "endkey", "reduce", "group", "group_level", "stale", "limit"]);
|
|
60
|
+
const keysAsString = `keys=${JSON.stringify(options.keys)}`;
|
|
61
|
+
if (keysAsString.length + qs.length + 1 <= MAX_URL_LENGTH) {
|
|
62
|
+
method = "GET";
|
|
63
|
+
if (qs.length > 0) qs += "&";
|
|
64
|
+
else qs = "?";
|
|
65
|
+
qs += keysAsString;
|
|
66
|
+
} else {
|
|
67
|
+
method = "POST";
|
|
68
|
+
payload = { keys: options.keys };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
logger.debug("Generated query string:", qs);
|
|
72
|
+
const url = `${config.couch}/${view}?${qs.toString()}`;
|
|
73
|
+
let results;
|
|
74
|
+
try {
|
|
75
|
+
logger.debug(`Sending ${method} request to: ${url}`);
|
|
76
|
+
results = method === "GET" ? await (0, import_needle.default)("get", url, opts) : await (0, import_needle.default)("post", url, payload, opts);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
logger.error("Network error during query:", err);
|
|
79
|
+
import_errors.RetryableError.handleNetworkError(err);
|
|
80
|
+
}
|
|
81
|
+
if (!results) {
|
|
82
|
+
logger.error("No response received from query request");
|
|
83
|
+
throw new import_errors.RetryableError("no response", 503);
|
|
84
|
+
}
|
|
85
|
+
const body = results.body;
|
|
86
|
+
if (import_errors.RetryableError.isRetryableStatusCode(results.statusCode)) {
|
|
87
|
+
logger.warn(`Retryable status code received: ${results.statusCode}`);
|
|
88
|
+
throw new import_errors.RetryableError(body.error || "retryable error during query", results.statusCode);
|
|
89
|
+
}
|
|
90
|
+
if (body.error) {
|
|
91
|
+
logger.error(`Query error: ${body.error}`);
|
|
92
|
+
throw new Error(body.error);
|
|
93
|
+
}
|
|
94
|
+
logger.info(`Successfully executed view query: ${view}`);
|
|
95
|
+
logger.debug("Query response:", body);
|
|
96
|
+
return body;
|
|
97
|
+
});
|
|
98
|
+
function queryString(options = {}, params) {
|
|
99
|
+
const parts = Object.keys(options).map((key) => {
|
|
100
|
+
let value = options[key];
|
|
101
|
+
if (includes(params, key)) {
|
|
102
|
+
if (typeof value === "string" && key !== "stale") value = `"${value}"`;
|
|
103
|
+
if (Array.isArray(value)) {
|
|
104
|
+
value = "[" + value.map((i) => {
|
|
105
|
+
if (i === null) return "null";
|
|
106
|
+
if (typeof i === "string") return `"${i}"`;
|
|
107
|
+
if (typeof i === "object" && Object.keys(i).length === 0) return "{}";
|
|
108
|
+
if (typeof i === "object") return JSON.stringify(i);
|
|
109
|
+
return i;
|
|
110
|
+
}).join(",") + "]";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return `${key}=${value}`;
|
|
114
|
+
});
|
|
115
|
+
return parts.join("&");
|
|
116
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var queryBuilder_exports = {};
|
|
20
|
+
__export(queryBuilder_exports, {
|
|
21
|
+
QueryBuilder: () => QueryBuilder,
|
|
22
|
+
createQuery: () => createQuery
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(queryBuilder_exports);
|
|
25
|
+
class QueryBuilder {
|
|
26
|
+
/** @type {QueryOptions} */
|
|
27
|
+
#options = {};
|
|
28
|
+
/**
|
|
29
|
+
* @param {any} key
|
|
30
|
+
* @returns {QueryBuilder}
|
|
31
|
+
*/
|
|
32
|
+
key(key) {
|
|
33
|
+
this.#options.key = key;
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @param {any} startkey
|
|
38
|
+
* @returns {QueryBuilder}
|
|
39
|
+
*/
|
|
40
|
+
startKey(startkey) {
|
|
41
|
+
this.#options.startkey = startkey;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* @param {any} endkey
|
|
46
|
+
* @returns {QueryBuilder}
|
|
47
|
+
*/
|
|
48
|
+
endKey(endkey) {
|
|
49
|
+
this.#options.endkey = endkey;
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @param {boolean} reduce
|
|
54
|
+
* @returns {QueryBuilder}
|
|
55
|
+
*/
|
|
56
|
+
reduce(reduce = true) {
|
|
57
|
+
this.#options.reduce = reduce;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @param {boolean} group
|
|
62
|
+
* @returns {QueryBuilder}
|
|
63
|
+
*/
|
|
64
|
+
group(group = true) {
|
|
65
|
+
this.#options.group = group;
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* @param {number} level
|
|
70
|
+
* @returns {QueryBuilder}
|
|
71
|
+
*/
|
|
72
|
+
groupLevel(level) {
|
|
73
|
+
this.#options.group_level = level;
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* @param {string} stale
|
|
78
|
+
* @returns {QueryBuilder}
|
|
79
|
+
*/
|
|
80
|
+
stale(stale) {
|
|
81
|
+
this.#options.stale = stale;
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* @param {number} limit
|
|
86
|
+
* @returns {QueryBuilder}
|
|
87
|
+
*/
|
|
88
|
+
limit(limit) {
|
|
89
|
+
this.#options.limit = limit;
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @returns {QueryOptions}
|
|
94
|
+
*/
|
|
95
|
+
build() {
|
|
96
|
+
return { ...this.#options };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const createQuery = () => new QueryBuilder();
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var retry_exports = {};
|
|
20
|
+
__export(retry_exports, {
|
|
21
|
+
withRetry: () => withRetry
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(retry_exports);
|
|
24
|
+
var import_errors = require("./errors.cjs");
|
|
25
|
+
var import_patch = require("./patch.cjs");
|
|
26
|
+
function withRetry(fn, options = {}) {
|
|
27
|
+
const {
|
|
28
|
+
maxRetries = 3,
|
|
29
|
+
initialDelay = 1e3,
|
|
30
|
+
// 1 second
|
|
31
|
+
backoffFactor = 2
|
|
32
|
+
// exponential backoff multiplier
|
|
33
|
+
} = options;
|
|
34
|
+
return async (...args) => {
|
|
35
|
+
let lastError;
|
|
36
|
+
let delay = initialDelay;
|
|
37
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
38
|
+
try {
|
|
39
|
+
return await fn(...args);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
lastError = error;
|
|
42
|
+
if (!(error instanceof import_errors.RetryableError)) {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
if (attempt === maxRetries) {
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
await (0, import_patch.sleep)(delay);
|
|
49
|
+
delay *= backoffFactor;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
throw lastError;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var stream_exports = {};
|
|
30
|
+
__export(stream_exports, {
|
|
31
|
+
queryStream: () => queryStream
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(stream_exports);
|
|
34
|
+
var import_needle = __toESM(require("needle"), 1);
|
|
35
|
+
var import_config = require("../schema/config.cjs");
|
|
36
|
+
var import_query = require("./query.cjs");
|
|
37
|
+
var import_errors = require("./errors.cjs");
|
|
38
|
+
var import_logger = require("./logger.cjs");
|
|
39
|
+
var import_JSONStream = __toESM(require("JSONStream"), 1);
|
|
40
|
+
const queryStream = (rawConfig, view, options, onRow) => new Promise((resolve, reject) => {
|
|
41
|
+
const config = import_config.CouchConfig.parse(rawConfig);
|
|
42
|
+
const logger = (0, import_logger.createLogger)(config);
|
|
43
|
+
logger.info(`Starting view query stream: ${view}`);
|
|
44
|
+
logger.debug("Query options:", options);
|
|
45
|
+
if (!options) options = {};
|
|
46
|
+
let method = "GET";
|
|
47
|
+
let payload = null;
|
|
48
|
+
let qs = (0, import_query.queryString)(options, ["key", "startkey", "endkey", "reduce", "group", "group_level", "stale", "limit"]);
|
|
49
|
+
logger.debug("Generated query string:", qs);
|
|
50
|
+
if (typeof options.keys !== "undefined") {
|
|
51
|
+
const MAX_URL_LENGTH = 2e3;
|
|
52
|
+
const keysAsString = `keys=${encodeURIComponent(JSON.stringify(options.keys))}`;
|
|
53
|
+
if (keysAsString.length + qs.length + 1 <= MAX_URL_LENGTH) {
|
|
54
|
+
qs += (qs[0] === "?" ? "&" : "?") + keysAsString;
|
|
55
|
+
} else {
|
|
56
|
+
method = "POST";
|
|
57
|
+
payload = { keys: options.keys };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const url = `${config.couch}/${view}?${qs.toString()}`;
|
|
61
|
+
const opts = {
|
|
62
|
+
json: true,
|
|
63
|
+
headers: {
|
|
64
|
+
"Content-Type": "application/json"
|
|
65
|
+
},
|
|
66
|
+
parse_response: false
|
|
67
|
+
// Keep as stream
|
|
68
|
+
};
|
|
69
|
+
const streamer = import_JSONStream.default.parse("rows.*");
|
|
70
|
+
let rowCount = 0;
|
|
71
|
+
streamer.on(
|
|
72
|
+
"data",
|
|
73
|
+
/** @param {object} row */
|
|
74
|
+
(row) => {
|
|
75
|
+
rowCount++;
|
|
76
|
+
onRow(row);
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
streamer.on(
|
|
80
|
+
"error",
|
|
81
|
+
/** @param {Error} err */
|
|
82
|
+
(err) => {
|
|
83
|
+
logger.error("Stream parsing error:", err);
|
|
84
|
+
reject(new Error(`Stream parsing error: ${err.message}`));
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
streamer.on(
|
|
88
|
+
"done",
|
|
89
|
+
/** @param {Error|null} err */
|
|
90
|
+
(err) => {
|
|
91
|
+
try {
|
|
92
|
+
import_errors.RetryableError.handleNetworkError(err);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
reject(e);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
streamer.on("end", () => {
|
|
99
|
+
logger.info(`Stream completed, processed ${rowCount} rows`);
|
|
100
|
+
resolve(void 0);
|
|
101
|
+
});
|
|
102
|
+
const req = method === "GET" ? import_needle.default.get(url, opts) : import_needle.default.post(url, payload, opts);
|
|
103
|
+
req.on("response", (response) => {
|
|
104
|
+
logger.debug(`Received response with status code: ${response.statusCode}`);
|
|
105
|
+
if (import_errors.RetryableError.isRetryableStatusCode(response.statusCode)) {
|
|
106
|
+
logger.warn(`Retryable status code received: ${response.statusCode}`);
|
|
107
|
+
reject(new import_errors.RetryableError("retryable error during stream query", response.statusCode));
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
req.on("error", (err) => {
|
|
111
|
+
logger.error("Network error during stream query:", err);
|
|
112
|
+
try {
|
|
113
|
+
import_errors.RetryableError.handleNetworkError(err);
|
|
114
|
+
} catch (retryErr) {
|
|
115
|
+
reject(retryErr);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
reject(err);
|
|
119
|
+
});
|
|
120
|
+
req.pipe(streamer);
|
|
121
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var lock_exports = {};
|
|
20
|
+
__export(lock_exports, {
|
|
21
|
+
createLock: () => createLock,
|
|
22
|
+
removeLock: () => removeLock
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(lock_exports);
|
|
25
|
+
var import_lock = require("../../schema/sugar/lock.cjs");
|
|
26
|
+
var import_crud = require("../crud.cjs");
|
|
27
|
+
var import_logger = require("../logger.cjs");
|
|
28
|
+
const createLock = import_lock.CreateLock.implement(async (config, docId, options) => {
|
|
29
|
+
const logger = (0, import_logger.createLogger)(config);
|
|
30
|
+
if (!options.enableLocking) {
|
|
31
|
+
logger.debug("Locking disabled, returning true");
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
const _id = `lock-${docId}`;
|
|
35
|
+
const lock = {
|
|
36
|
+
_id,
|
|
37
|
+
type: "lock",
|
|
38
|
+
locks: docId,
|
|
39
|
+
lockedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40
|
+
lockedBy: options.username
|
|
41
|
+
};
|
|
42
|
+
try {
|
|
43
|
+
const result = await (0, import_crud.put)(config, lock);
|
|
44
|
+
logger.info(`Lock created for ${docId} by ${options.username}`);
|
|
45
|
+
return result.ok === true;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (error.status === 409) {
|
|
48
|
+
logger.warn(`Lock conflict for ${docId} - already locked`);
|
|
49
|
+
} else {
|
|
50
|
+
logger.error(`Error creating lock for ${docId}:`, error);
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const removeLock = import_lock.RemoveLock.implement(async (config, docId, options) => {
|
|
56
|
+
const logger = (0, import_logger.createLogger)(config);
|
|
57
|
+
if (!options.enableLocking) {
|
|
58
|
+
logger.debug("Locking disabled, skipping unlock");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (!docId) {
|
|
62
|
+
logger.warn("No docId provided for unlock");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const _id = `lock-${docId}`;
|
|
66
|
+
const existingLock = await (0, import_crud.get)(config, _id);
|
|
67
|
+
if (!existingLock) {
|
|
68
|
+
logger.debug(`No lock found for ${docId}`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (existingLock.lockedBy !== options.username) {
|
|
72
|
+
logger.warn(`Cannot remove lock for ${docId} - owned by ${existingLock.lockedBy}`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
await (0, import_crud.put)(config, { ...existingLock, _deleted: true });
|
|
77
|
+
logger.info(`Lock removed for ${docId}`);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
logger.error(`Error removing lock for ${docId}:`, error);
|
|
80
|
+
}
|
|
81
|
+
});
|