hide-a-bed 4.0.1 → 4.0.2

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.
Files changed (52) hide show
  1. package/cjs/impl/bulk.cjs +1 -8
  2. package/cjs/impl/logger.cjs +19 -10
  3. package/cjs/impl/patch.cjs +21 -2
  4. package/cjs/impl/query.cjs +18 -2
  5. package/cjs/impl/stream.cjs +10 -2
  6. package/cjs/index.cjs +1 -0
  7. package/cjs/schema/config.cjs +1 -0
  8. package/cjs/schema/stream.cjs +1 -1
  9. package/impl/bulk.d.mts +7 -0
  10. package/impl/bulk.d.mts.map +1 -0
  11. package/impl/bulk.mjs +4 -12
  12. package/impl/crud.d.mts +5 -0
  13. package/impl/crud.d.mts.map +1 -0
  14. package/impl/crud.mjs +7 -7
  15. package/impl/errors.d.mts +35 -0
  16. package/impl/errors.d.mts.map +1 -0
  17. package/impl/errors.mjs +11 -11
  18. package/impl/logger.d.mts +32 -0
  19. package/impl/logger.d.mts.map +1 -0
  20. package/impl/logger.mjs +1 -1
  21. package/impl/patch.d.mts +4 -0
  22. package/impl/patch.d.mts.map +1 -0
  23. package/impl/patch.mjs +6 -7
  24. package/impl/query.d.mts +173 -0
  25. package/impl/query.d.mts.map +1 -0
  26. package/impl/query.mjs +1 -5
  27. package/impl/retry.d.mts +2 -0
  28. package/impl/retry.d.mts.map +1 -0
  29. package/impl/retry.mjs +3 -3
  30. package/impl/stream.d.mts +3 -0
  31. package/impl/stream.d.mts.map +1 -0
  32. package/impl/stream.mjs +9 -25
  33. package/index.d.mts +41 -0
  34. package/index.d.mts.map +1 -0
  35. package/index.mjs +1 -1
  36. package/package.json +1 -1
  37. package/schema/bind.d.mts +473 -0
  38. package/schema/bind.d.mts.map +1 -0
  39. package/schema/bulk.d.mts +367 -0
  40. package/schema/bulk.d.mts.map +1 -0
  41. package/schema/config.d.mts +79 -0
  42. package/schema/config.d.mts.map +1 -0
  43. package/schema/config.mjs +2 -2
  44. package/schema/crud.d.mts +266 -0
  45. package/schema/crud.d.mts.map +1 -0
  46. package/schema/patch.d.mts +119 -0
  47. package/schema/patch.d.mts.map +1 -0
  48. package/schema/query.d.mts +365 -0
  49. package/schema/query.d.mts.map +1 -0
  50. package/schema/query.mjs +1 -1
  51. package/schema/stream.d.mts +196 -0
  52. package/schema/stream.d.mts.map +1 -0
package/cjs/impl/bulk.cjs CHANGED
@@ -104,14 +104,7 @@ const bulkGet = import_bulk.BulkGet.implement(async (config, ids) => {
104
104
  throw new Error("could not fetch");
105
105
  }
106
106
  const rows = resp?.body?.rows || [];
107
- const docs = [];
108
- rows.forEach((r) => {
109
- if (r.error) return;
110
- if (!r.key) return;
111
- if (!r.doc) return;
112
- const doc = r.doc;
113
- docs.push(doc);
114
- });
107
+ const docs = rows.map((r) => r.doc);
115
108
  logger.info(`Successfully retrieved ${docs.length} documents`);
116
109
  return docs;
117
110
  });
@@ -26,16 +26,25 @@ function createLogger(config) {
26
26
  return config._normalizedLogger;
27
27
  }
28
28
  if (!config.logger) {
29
- config._normalizedLogger = {
30
- error: () => {
31
- },
32
- warn: () => {
33
- },
34
- info: () => {
35
- },
36
- debug: () => {
37
- }
38
- };
29
+ if (config.useConsoleLogger) {
30
+ config._normalizedLogger = {
31
+ error: (...args) => console.error(...args),
32
+ warn: (...args) => console.warn(...args),
33
+ info: (...args) => console.info(...args),
34
+ debug: (...args) => console.debug(...args)
35
+ };
36
+ } else {
37
+ config._normalizedLogger = {
38
+ error: () => {
39
+ },
40
+ warn: () => {
41
+ },
42
+ info: () => {
43
+ },
44
+ debug: () => {
45
+ }
46
+ };
47
+ }
39
48
  return config._normalizedLogger;
40
49
  }
41
50
  if (typeof config.logger === "function") {
@@ -24,34 +24,53 @@ __export(patch_exports, {
24
24
  module.exports = __toCommonJS(patch_exports);
25
25
  var import_crud = require("./crud.cjs");
26
26
  var import_patch = require("../schema/patch.cjs");
27
+ var import_logger = require("./logger.cjs");
27
28
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
28
29
  const patch = import_patch.Patch.implement(async (config, id, properties) => {
30
+ const logger = (0, import_logger.createLogger)(config);
29
31
  const maxRetries = config.maxRetries || 5;
30
32
  let delay = config.initialDelay || 1e3;
31
33
  let attempts = 0;
34
+ logger.info(`Starting patch operation for document ${id}`);
35
+ logger.debug("Patch properties:", properties);
32
36
  while (attempts <= maxRetries) {
37
+ logger.debug(`Attempt ${attempts + 1} of ${maxRetries + 1}`);
33
38
  try {
34
39
  const doc = await (0, import_crud.get)(config, id);
35
- if (!doc) return { ok: false, statusCode: 404, error: "not_found" };
40
+ if (!doc) {
41
+ logger.warn(`Document ${id} not found`);
42
+ return { ok: false, statusCode: 404, error: "not_found" };
43
+ }
36
44
  const updatedDoc = { ...doc, ...properties };
45
+ logger.debug("Merged document:", updatedDoc);
37
46
  const result = await (0, import_crud.put)(config, updatedDoc);
38
47
  if (result.ok) {
48
+ logger.info(`Successfully patched document ${id}, rev: ${result.rev}`);
39
49
  return result;
40
50
  }
41
51
  attempts++;
42
52
  if (attempts > maxRetries) {
53
+ logger.error(`Failed to patch ${id} after ${maxRetries} attempts`);
43
54
  throw new Error(`Failed to patch after ${maxRetries} attempts`);
44
55
  }
56
+ logger.warn(`Conflict detected for ${id}, retrying (attempt ${attempts})`);
45
57
  await sleep(delay);
46
58
  delay *= config.backoffFactor;
59
+ logger.debug(`Next retry delay: ${delay}ms`);
47
60
  } catch (err) {
48
- if (err.message !== "not_found") return { ok: false, statusCode: 404, error: "not_found" };
61
+ if (err.message === "not_found") {
62
+ logger.warn(`Document ${id} not found during patch operation`);
63
+ return { ok: false, statusCode: 404, error: "not_found" };
64
+ }
49
65
  attempts++;
50
66
  if (attempts > maxRetries) {
51
67
  const error = `Failed to patch after ${maxRetries} attempts: ${err.message}`;
68
+ logger.error(error);
52
69
  return { ok: false, statusCode: 500, error };
53
70
  }
71
+ logger.warn(`Error during patch attempt ${attempts}: ${err.message}`);
54
72
  await sleep(delay);
73
+ logger.debug(`Retrying after ${delay}ms`);
55
74
  }
56
75
  }
57
76
  });
@@ -36,10 +36,15 @@ var import_zod = require("zod");
36
36
  var import_needle = __toESM(require("needle"), 1);
37
37
  var import_query = require("../schema/query.cjs");
38
38
  var import_errors = require("./errors.cjs");
39
+ var import_logger = require("./logger.cjs");
39
40
  var import_lodash = __toESM(require("lodash"), 1);
40
41
  const { includes } = import_lodash.default;
41
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);
42
46
  const qs = queryString(options, ["key", "startkey", "endkey", "reduce", "group", "group_level", "stale", "limit"]);
47
+ logger.debug("Generated query string:", qs);
43
48
  const opts = {
44
49
  json: true,
45
50
  headers: {
@@ -49,16 +54,27 @@ const query = import_query.SimpleViewQuery.implement(async (config, view, option
49
54
  const url = `${config.couch}/${view}?${qs.toString()}`;
50
55
  let results;
51
56
  try {
57
+ logger.debug(`Sending GET request to: ${url}`);
52
58
  results = await (0, import_needle.default)("get", url, opts);
53
59
  } catch (err) {
60
+ logger.error("Network error during query:", err);
54
61
  import_errors.RetryableError.handleNetworkError(err);
55
62
  }
56
- if (!results) throw new import_errors.RetryableError("no response", 503);
63
+ if (!results) {
64
+ logger.error("No response received from query request");
65
+ throw new import_errors.RetryableError("no response", 503);
66
+ }
57
67
  const body = results.body;
58
68
  if (import_errors.RetryableError.isRetryableStatusCode(results.statusCode)) {
69
+ logger.warn(`Retryable status code received: ${results.statusCode}`);
59
70
  throw new import_errors.RetryableError(body.error || "retryable error during query", results.statusCode);
60
71
  }
61
- if (body.error) throw new Error(body.error);
72
+ if (body.error) {
73
+ logger.error(`Query error: ${body.error}`);
74
+ throw new Error(body.error);
75
+ }
76
+ logger.info(`Successfully executed view query: ${view}`);
77
+ logger.debug("Query response:", body);
62
78
  return body;
63
79
  });
64
80
  function queryString(options, params) {
@@ -34,6 +34,7 @@ module.exports = __toCommonJS(stream_exports);
34
34
  var import_needle = __toESM(require("needle"), 1);
35
35
  var import_query = require("./query.cjs");
36
36
  var import_errors = require("./errors.cjs");
37
+ var import_logger = require("./logger.cjs");
37
38
  var import_JSONStream = __toESM(require("JSONStream"), 1);
38
39
  const queryStream = (config, view, options, onRow) => new Promise((resolve, reject) => {
39
40
  if (!options) options = {};
@@ -48,7 +49,15 @@ const queryStream = (config, view, options, onRow) => new Promise((resolve, reje
48
49
  // Keep as stream
49
50
  };
50
51
  const streamer = import_JSONStream.default.parse("rows.*");
51
- streamer.on("data", onRow);
52
+ let rowCount = 0;
53
+ streamer.on(
54
+ "data",
55
+ /** @param {object} row */
56
+ (row) => {
57
+ rowCount++;
58
+ onRow(row);
59
+ }
60
+ );
52
61
  streamer.on(
53
62
  "error",
54
63
  /** @param {Error} err */
@@ -74,7 +83,6 @@ const queryStream = (config, view, options, onRow) => new Promise((resolve, reje
74
83
  req.on("response", (response) => {
75
84
  if (import_errors.RetryableError.isRetryableStatusCode(response.statusCode)) {
76
85
  reject(new import_errors.RetryableError("retryable error during stream query", response.statusCode));
77
- return;
78
86
  }
79
87
  });
80
88
  req.on("error", (err) => {
package/cjs/index.cjs CHANGED
@@ -52,6 +52,7 @@ const schema = {
52
52
  OnRow: import_stream2.OnRow,
53
53
  BulkSave: import_bulk2.BulkSave,
54
54
  BulkGet: import_bulk2.BulkGet,
55
+ BulkRemove: import_bulk2.BulkRemove,
55
56
  CouchGet: import_crud2.CouchGet,
56
57
  CouchPut: import_crud2.CouchPut,
57
58
  CouchDoc: import_crud2.CouchDoc,
@@ -40,6 +40,7 @@ const CouchConfig = import_zod.z.object({
40
40
  maxRetries: import_zod.z.number().optional().default(3).describe("maximum number of retry attempts"),
41
41
  initialDelay: import_zod.z.number().optional().default(1e3).describe("initial retry delay in milliseconds"),
42
42
  backoffFactor: import_zod.z.number().optional().default(2).describe("multiplier for exponential backoff"),
43
+ useConsoleLogger: import_zod.z.boolean().optional().default(false).describe("turn on console as a fallback logger"),
43
44
  logger: LoggerSchema.optional().describe("logging interface supporting winston-like or simple function interface"),
44
45
  _normalizedLogger: import_zod.z.any().optional()
45
46
  // Internal property for caching normalized logger
@@ -28,7 +28,7 @@ var import_config = require("./config.cjs");
28
28
  var import_query = require("./query.cjs");
29
29
  const OnRow = import_zod.z.function().args(
30
30
  import_query.ViewRow
31
- ).returns(import_zod.z.undefined());
31
+ );
32
32
  const SimpleViewQueryStream = import_zod.z.function().args(
33
33
  import_config.CouchConfig,
34
34
  import_zod.z.string().describe("the view name"),
@@ -0,0 +1,7 @@
1
+ /** @type { import('../schema/bulk.mjs').BulkSaveSchema } */
2
+ export const bulkSave: import("../schema/bulk.mjs").BulkSaveSchema;
3
+ /** @type { import('../schema/bulk.mjs').BulkGetSchema } */
4
+ export const bulkGet: import("../schema/bulk.mjs").BulkGetSchema;
5
+ /** @type { import('../schema/bulk.mjs').BulkRemoveSchema } */
6
+ export const bulkRemove: import("../schema/bulk.mjs").BulkRemoveSchema;
7
+ //# sourceMappingURL=bulk.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk.d.mts","sourceRoot":"","sources":["bulk.mjs"],"names":[],"mappings":"AAaA,4DAA4D;AAC5D,uBADY,OAAO,oBAAoB,EAAE,cAAc,CAsCrD;AAEF,2DAA2D;AAC3D,sBADY,OAAO,oBAAoB,EAAE,aAAa,CAkCpD;AAEF,8DAA8D;AAC9D,yBADY,OAAO,oBAAoB,EAAE,gBAAgB,CAOvD"}
package/impl/bulk.mjs CHANGED
@@ -15,7 +15,7 @@ const opts = {
15
15
  export const bulkSave = BulkSave.implement(async (config, docs) => {
16
16
  /** @type {import('./logger.mjs').Logger } */
17
17
  const logger = createLogger(config)
18
-
18
+
19
19
  if (!docs) {
20
20
  logger.warn('bulkSave called with no docs')
21
21
  return { ok: false, error: 'noDocs', reason: 'no docs provided' }
@@ -55,7 +55,7 @@ export const bulkSave = BulkSave.implement(async (config, docs) => {
55
55
  export const bulkGet = BulkGet.implement(async (config, ids) => {
56
56
  const logger = createLogger(config)
57
57
  const keys = ids
58
-
58
+
59
59
  logger.info(`Starting bulk get for ${keys.length} documents`)
60
60
  const url = `${config.couch}/_all_docs?include_docs=true`
61
61
  const body = { keys }
@@ -80,17 +80,9 @@ export const bulkGet = BulkGet.implement(async (config, ids) => {
80
80
  }
81
81
  const rows = resp?.body?.rows || []
82
82
  /** @type {Array<import('../schema/crud.mjs').CouchDocSchema>} */
83
- const docs = []
84
- rows.forEach((
83
+ const docs = rows.map((
85
84
  /** @type {{ error?: any, key?: string, doc?: import('../schema/crud.mjs').CouchDocSchema }} */ r
86
- ) => {
87
- if (r.error) return
88
- if (!r.key) return
89
- if (!r.doc) return
90
- /** @type { import('../schema/crud.mjs').CouchDocSchema } */
91
- const doc = r.doc
92
- docs.push(doc)
93
- })
85
+ ) => r.doc)
94
86
  logger.info(`Successfully retrieved ${docs.length} documents`)
95
87
  return docs
96
88
  })
@@ -0,0 +1,5 @@
1
+ /** @type { import('../schema/crud.mjs').CouchGetSchema } */
2
+ export const get: import("../schema/crud.mjs").CouchGetSchema;
3
+ /** @type { import('../schema/crud.mjs').CouchPutSchema } */
4
+ export const put: import("../schema/crud.mjs").CouchPutSchema;
5
+ //# sourceMappingURL=crud.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.d.mts","sourceRoot":"","sources":["crud.mjs"],"names":[],"mappings":"AAaA,4DAA4D;AAC5D,kBADY,OAAO,oBAAoB,EAAE,cAAc,CAwCrD;AAEF,4DAA4D;AAC5D,kBADY,OAAO,oBAAoB,EAAE,cAAc,CAqCrD"}
package/impl/crud.mjs CHANGED
@@ -16,7 +16,7 @@ export const get = CouchGet.implement(async (config, id) => {
16
16
  const logger = createLogger(config)
17
17
  const url = `${config.couch}/${id}`
18
18
  logger.info(`Getting document with id: ${id}`)
19
-
19
+
20
20
  try {
21
21
  const resp = await needle('get', url, opts)
22
22
  if (!resp) {
@@ -58,7 +58,7 @@ export const put = CouchPut.implement(async (config, doc) => {
58
58
  const logger = createLogger(config)
59
59
  const url = `${config.couch}/${doc._id}`
60
60
  const body = doc
61
-
61
+
62
62
  logger.info(`Putting document with id: ${doc._id}`)
63
63
  let resp
64
64
  try {
@@ -67,27 +67,27 @@ export const put = CouchPut.implement(async (config, doc) => {
67
67
  logger.error('Error during put operation:', err)
68
68
  RetryableError.handleNetworkError(err)
69
69
  }
70
-
70
+
71
71
  if (!resp) {
72
72
  logger.error('No response received from put request')
73
73
  throw new RetryableError('no response', 503)
74
74
  }
75
-
75
+
76
76
  const result = resp?.body || {}
77
77
  result.statusCode = resp.statusCode
78
-
78
+
79
79
  if (resp.statusCode === 409) {
80
80
  logger.warn(`Conflict detected for document: ${doc._id}`)
81
81
  result.ok = false
82
82
  result.error = 'conflict'
83
83
  return result
84
84
  }
85
-
85
+
86
86
  if (RetryableError.isRetryableStatusCode(resp.statusCode)) {
87
87
  logger.warn(`Retryable status code received: ${resp.statusCode}`)
88
88
  throw new RetryableError(result.reason || 'retryable error', resp.statusCode)
89
89
  }
90
-
90
+
91
91
  logger.info(`Successfully saved document: ${doc._id}`)
92
92
  return result
93
93
  })
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @typedef {Object} NetworkError
3
+ * @property {string} code - The error code
4
+ * @property {string} [message] - Optional error message
5
+ */
6
+ export class RetryableError extends Error {
7
+ /**
8
+ * @param {number|undefined} statusCode - The HTTP status code to check
9
+ * @returns {boolean} Whether the status code is retryable
10
+ */
11
+ static isRetryableStatusCode(statusCode: number | undefined): boolean;
12
+ /**
13
+ * @param {NetworkError | unknown} err - The network error to handle
14
+ * @throws {RetryableError} If the error is retryable
15
+ * @throws {Error} If the error is not retryable
16
+ */
17
+ static handleNetworkError(err: NetworkError | unknown): void;
18
+ /**
19
+ * @param {string} message - The error message
20
+ * @param {number|undefined} statusCode - The HTTP status code
21
+ */
22
+ constructor(message: string, statusCode: number | undefined);
23
+ statusCode: number | undefined;
24
+ }
25
+ export type NetworkError = {
26
+ /**
27
+ * - The error code
28
+ */
29
+ code: string;
30
+ /**
31
+ * - Optional error message
32
+ */
33
+ message?: string | undefined;
34
+ };
35
+ //# sourceMappingURL=errors.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.mts","sourceRoot":"","sources":["errors.mjs"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH;IAWE;;;OAGG;IACH,yCAHW,MAAM,GAAC,SAAS,GACd,OAAO,CAKnB;IAED;;;;OAIG;IACH,+BAJW,YAAY,GAAG,OAAO,QAsBhC;IA1CD;;;OAGG;IACH,qBAHW,MAAM,cACN,MAAM,GAAC,SAAS,EAM1B;IADC,+BAA4B;CAoC/B;;;;;UAhDa,MAAM"}
package/impl/errors.mjs CHANGED
@@ -11,19 +11,19 @@ export class RetryableError extends Error {
11
11
  * @param {string} message - The error message
12
12
  * @param {number|undefined} statusCode - The HTTP status code
13
13
  */
14
- constructor(message, statusCode) {
15
- super(message);
16
- this.name = 'RetryableError';
17
- this.statusCode = statusCode;
14
+ constructor (message, statusCode) {
15
+ super(message)
16
+ this.name = 'RetryableError'
17
+ this.statusCode = statusCode
18
18
  }
19
19
 
20
20
  /**
21
21
  * @param {number|undefined} statusCode - The HTTP status code to check
22
22
  * @returns {boolean} Whether the status code is retryable
23
23
  */
24
- static isRetryableStatusCode(statusCode) {
25
- if (statusCode === undefined) return false;
26
- return [408, 429, 500, 502, 503, 504].includes(statusCode);
24
+ static isRetryableStatusCode (statusCode) {
25
+ if (statusCode === undefined) return false
26
+ return [408, 429, 500, 502, 503, 504].includes(statusCode)
27
27
  }
28
28
 
29
29
  /**
@@ -31,7 +31,7 @@ export class RetryableError extends Error {
31
31
  * @throws {RetryableError} If the error is retryable
32
32
  * @throws {Error} If the error is not retryable
33
33
  */
34
- static handleNetworkError(err) {
34
+ static handleNetworkError (err) {
35
35
  /** @type {Record<string, number>} */
36
36
  const networkErrors = {
37
37
  ECONNREFUSED: 503,
@@ -42,12 +42,12 @@ export class RetryableError extends Error {
42
42
  EPIPE: 503,
43
43
  EHOSTUNREACH: 503,
44
44
  ESOCKETTIMEDOUT: 503
45
- };
45
+ }
46
46
 
47
47
  // Type guard for NetworkError shape
48
48
  if (typeof err === 'object' && err !== null && 'code' in err && typeof err.code === 'string' && networkErrors[err.code]) {
49
- throw new RetryableError(`Network error: ${err.code}`, networkErrors[err.code]);
49
+ throw new RetryableError(`Network error: ${err.code}`, networkErrors[err.code])
50
50
  }
51
- throw err;
51
+ throw err
52
52
  }
53
53
  }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @typedef {Object} Logger
3
+ * @property {(...args: any[]) => void} error - Log error messages
4
+ * @property {(...args: any[]) => void} warn - Log warning messages
5
+ * @property {(...args: any[]) => void} info - Log info messages
6
+ * @property {(...args: any[]) => void} debug - Log debug messages
7
+ */
8
+ /**
9
+ * Creates a unified logger interface that works with both function and object-style loggers
10
+ * @param {import('../schema/config.mjs').CouchConfigSchema} config
11
+ * @returns {Logger} Normalized logger interface
12
+ */
13
+ export function createLogger(config: import("../schema/config.mjs").CouchConfigSchema): Logger;
14
+ export type Logger = {
15
+ /**
16
+ * - Log error messages
17
+ */
18
+ error: (...args: any[]) => void;
19
+ /**
20
+ * - Log warning messages
21
+ */
22
+ warn: (...args: any[]) => void;
23
+ /**
24
+ * - Log info messages
25
+ */
26
+ info: (...args: any[]) => void;
27
+ /**
28
+ * - Log debug messages
29
+ */
30
+ debug: (...args: any[]) => void;
31
+ };
32
+ //# sourceMappingURL=logger.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.mts","sourceRoot":"","sources":["logger.mjs"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;GAIG;AACH,qCAHW,OAAO,sBAAsB,EAAE,iBAAiB,GAC9C,MAAM,CA+ClB;;;;;WAxDa,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;;;;UACxB,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;;;;UACxB,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;;;;WACxB,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI"}
package/impl/logger.mjs CHANGED
@@ -11,7 +11,7 @@
11
11
  * @param {import('../schema/config.mjs').CouchConfigSchema} config
12
12
  * @returns {Logger} Normalized logger interface
13
13
  */
14
- export function createLogger(config) {
14
+ export function createLogger (config) {
15
15
  // Return cached logger if it exists
16
16
  if (config._normalizedLogger) {
17
17
  return config._normalizedLogger
@@ -0,0 +1,4 @@
1
+ export function sleep(ms: any): Promise<any>;
2
+ /** @type { import('../schema/patch.mjs').PatchSchema } */
3
+ export const patch: import("../schema/patch.mjs").PatchSchema;
4
+ //# sourceMappingURL=patch.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch.d.mts","sourceRoot":"","sources":["patch.mjs"],"names":[],"mappings":"AAIO,6CAAmE;AAE1E,0DAA0D;AAC1D,oBADY,OAAO,qBAAqB,EAAE,WAAW,CA4DnD"}
package/impl/patch.mjs CHANGED
@@ -22,10 +22,10 @@ export const patch = Patch.implement(async (config, id, properties) => {
22
22
  logger.warn(`Document ${id} not found`)
23
23
  return { ok: false, statusCode: 404, error: 'not_found' }
24
24
  }
25
-
25
+
26
26
  const updatedDoc = { ...doc, ...properties }
27
27
  logger.debug('Merged document:', updatedDoc)
28
-
28
+
29
29
  const result = await put(config, updatedDoc)
30
30
 
31
31
  // Check if the response indicates a conflict
@@ -33,25 +33,24 @@ export const patch = Patch.implement(async (config, id, properties) => {
33
33
  logger.info(`Successfully patched document ${id}, rev: ${result.rev}`)
34
34
  return result
35
35
  }
36
-
36
+
37
37
  // If not ok, treat as conflict and retry
38
38
  attempts++
39
39
  if (attempts > maxRetries) {
40
40
  logger.error(`Failed to patch ${id} after ${maxRetries} attempts`)
41
41
  throw new Error(`Failed to patch after ${maxRetries} attempts`)
42
42
  }
43
-
43
+
44
44
  logger.warn(`Conflict detected for ${id}, retrying (attempt ${attempts})`)
45
45
  await sleep(delay)
46
46
  delay *= config.backoffFactor
47
47
  logger.debug(`Next retry delay: ${delay}ms`)
48
-
49
48
  } catch (err) {
50
49
  if (err.message === 'not_found') {
51
50
  logger.warn(`Document ${id} not found during patch operation`)
52
51
  return { ok: false, statusCode: 404, error: 'not_found' }
53
52
  }
54
-
53
+
55
54
  // Handle other errors (network, etc)
56
55
  attempts++
57
56
  if (attempts > maxRetries) {
@@ -59,7 +58,7 @@ export const patch = Patch.implement(async (config, id, properties) => {
59
58
  logger.error(error)
60
59
  return { ok: false, statusCode: 500, error }
61
60
  }
62
-
61
+
63
62
  logger.warn(`Error during patch attempt ${attempts}: ${err.message}`)
64
63
  await sleep(delay)
65
64
  logger.debug(`Retrying after ${delay}ms`)