@siteping/adapter-drizzle 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{chunk-6G6UAERF.js → chunk-6DO75JHR.js} +80 -35
- package/dist/chunk-6DO75JHR.js.map +1 -0
- package/dist/deep-link.d.cts +10 -0
- package/dist/deep-link.d.ts +10 -0
- package/dist/errors.d.cts +46 -16
- package/dist/errors.d.ts +46 -16
- package/dist/i18n.d.cts +14 -10
- package/dist/i18n.d.ts +14 -10
- package/dist/index.d.cts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/libsql.cjs +86 -41
- package/dist/libsql.cjs.map +1 -1
- package/dist/libsql.d.cts +3 -2
- package/dist/libsql.d.ts +3 -2
- package/dist/libsql.js +12 -2
- package/dist/libsql.js.map +1 -1
- package/dist/logger.d.cts +30 -0
- package/dist/logger.d.ts +30 -0
- package/dist/pg.cjs +86 -41
- package/dist/pg.cjs.map +1 -1
- package/dist/pg.d.cts +3 -2
- package/dist/pg.d.ts +3 -2
- package/dist/pg.js +12 -2
- package/dist/pg.js.map +1 -1
- package/dist/schema.d.cts +31 -0
- package/dist/schema.d.ts +31 -0
- package/dist/screenshot-storage.d.cts +14 -17
- package/dist/screenshot-storage.d.ts +14 -17
- package/dist/siteping-core.d.cts +8 -5
- package/dist/siteping-core.d.ts +8 -5
- package/dist/store-helpers.d.cts +13 -9
- package/dist/store-helpers.d.ts +13 -9
- package/dist/text.d.cts +28 -0
- package/dist/text.d.ts +28 -0
- package/dist/types.d.cts +116 -39
- package/dist/types.d.ts +116 -39
- package/dist/wire.d.cts +6 -1
- package/dist/wire.d.ts +6 -1
- package/package.json +4 -4
- package/dist/chunk-6G6UAERF.js.map +0 -1
package/README.md
CHANGED
|
@@ -41,6 +41,13 @@ var StoreLimitError = class extends Error {
|
|
|
41
41
|
this.name = "StoreLimitError";
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
|
+
var StoreValueTooLongError = class extends Error {
|
|
45
|
+
code = "STORE_VALUE_TOO_LONG";
|
|
46
|
+
constructor(message = "Value too long for the store", options) {
|
|
47
|
+
super(message, options);
|
|
48
|
+
this.name = "StoreValueTooLongError";
|
|
49
|
+
}
|
|
50
|
+
};
|
|
44
51
|
function hasErrorCode(error, code) {
|
|
45
52
|
return hasOwn(error, "code") && error.code === code;
|
|
46
53
|
}
|
|
@@ -56,6 +63,14 @@ function isStorePersistence(error) {
|
|
|
56
63
|
if (error instanceof StorePersistenceError) return true;
|
|
57
64
|
return hasErrorCode(error, "STORE_PERSISTENCE");
|
|
58
65
|
}
|
|
66
|
+
function isStoreLimit(error) {
|
|
67
|
+
if (error instanceof StoreLimitError) return true;
|
|
68
|
+
return hasErrorCode(error, "STORE_LIMIT");
|
|
69
|
+
}
|
|
70
|
+
function isStoreValueTooLong(error) {
|
|
71
|
+
if (error instanceof StoreValueTooLongError) return true;
|
|
72
|
+
return hasErrorCode(error, "STORE_VALUE_TOO_LONG");
|
|
73
|
+
}
|
|
59
74
|
|
|
60
75
|
// ../core/src/concurrency.ts
|
|
61
76
|
async function settleWithConcurrencyLimit(items, concurrency, task) {
|
|
@@ -92,6 +107,15 @@ function isUnreachableOffset(skip) {
|
|
|
92
107
|
return !Number.isSafeInteger(skip);
|
|
93
108
|
}
|
|
94
109
|
|
|
110
|
+
// ../core/src/logger.ts
|
|
111
|
+
function warnSafely(logger, message, context) {
|
|
112
|
+
try {
|
|
113
|
+
Promise.resolve(logger.warn(message, context)).catch(() => {
|
|
114
|
+
});
|
|
115
|
+
} catch {
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
95
119
|
// ../core/src/screenshot-storage.ts
|
|
96
120
|
var SCREENSHOT_DELETE_CONCURRENCY = 32;
|
|
97
121
|
function screenshotMimeType(dataUrl) {
|
|
@@ -164,6 +188,26 @@ function buildFeedbackRecord(input, ctx) {
|
|
|
164
188
|
};
|
|
165
189
|
}
|
|
166
190
|
|
|
191
|
+
// ../core/src/text.ts
|
|
192
|
+
var UNSTORABLE_CODE_UNITS = /\0|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
|
|
193
|
+
var REPLACEMENT_CHARACTER = "\uFFFD";
|
|
194
|
+
function toStorableText(text) {
|
|
195
|
+
return text.replace(UNSTORABLE_CODE_UNITS, REPLACEMENT_CHARACTER);
|
|
196
|
+
}
|
|
197
|
+
function isPlainObject(value) {
|
|
198
|
+
if (typeof value !== "object" || value === null) return false;
|
|
199
|
+
const prototype = Object.getPrototypeOf(value);
|
|
200
|
+
return prototype === Object.prototype || prototype === null;
|
|
201
|
+
}
|
|
202
|
+
function toStorableValue(value) {
|
|
203
|
+
if (typeof value === "string") return toStorableText(value);
|
|
204
|
+
if (Array.isArray(value)) return value.map(toStorableValue);
|
|
205
|
+
if (!isPlainObject(value)) return value;
|
|
206
|
+
return Object.fromEntries(
|
|
207
|
+
Object.entries(value).map(([key, item]) => [toStorableText(key), toStorableValue(item)])
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
167
211
|
// src/constants/errors.ts
|
|
168
212
|
var DRIZZLE_STORE_MESSAGE_PREFIX = "[siteping] DrizzleStore";
|
|
169
213
|
var DRIZZLE_QUERY_ERROR_MESSAGE_PREFIX = "Failed query:";
|
|
@@ -229,28 +273,6 @@ function withDriverErrors(gateway) {
|
|
|
229
273
|
});
|
|
230
274
|
}
|
|
231
275
|
|
|
232
|
-
// src/constants/text.ts
|
|
233
|
-
var UNSTORABLE_CODE_UNITS = /\0|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
|
|
234
|
-
var REPLACEMENT_CHARACTER = "\uFFFD";
|
|
235
|
-
|
|
236
|
-
// src/shared/text.ts
|
|
237
|
-
function toStorableText(text) {
|
|
238
|
-
return text.replace(UNSTORABLE_CODE_UNITS, REPLACEMENT_CHARACTER);
|
|
239
|
-
}
|
|
240
|
-
function isPlainObject(value) {
|
|
241
|
-
if (typeof value !== "object" || value === null) return false;
|
|
242
|
-
const prototype = Object.getPrototypeOf(value);
|
|
243
|
-
return prototype === Object.prototype || prototype === null;
|
|
244
|
-
}
|
|
245
|
-
function toStorableValue(value) {
|
|
246
|
-
if (typeof value === "string") return toStorableText(value);
|
|
247
|
-
if (Array.isArray(value)) return value.map(toStorableValue);
|
|
248
|
-
if (!isPlainObject(value)) return value;
|
|
249
|
-
return Object.fromEntries(
|
|
250
|
-
Object.entries(value).map(([key, item]) => [toStorableText(key), toStorableValue(item)])
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
276
|
// src/shared/store.ts
|
|
255
277
|
var silentLogger = {
|
|
256
278
|
warn() {
|
|
@@ -303,8 +325,11 @@ var DrizzleSitepingStore = class {
|
|
|
303
325
|
this.logger = options.logger ?? silentLogger;
|
|
304
326
|
this.now = options.now ?? systemClock;
|
|
305
327
|
}
|
|
328
|
+
/** Throws `StoreDuplicateError` when a feedback with the same `clientId` exists. */
|
|
306
329
|
async createFeedback(data) {
|
|
307
|
-
|
|
330
|
+
const { feedback, created } = await this.createFeedbackIfAbsent(data);
|
|
331
|
+
if (!created) throw new StoreDuplicateError(`A feedback with clientId ${data.clientId} already exists`);
|
|
332
|
+
return feedback;
|
|
308
333
|
}
|
|
309
334
|
/**
|
|
310
335
|
* Insert the feedback unless a row with the same `clientId` exists. The
|
|
@@ -486,7 +511,15 @@ var DrizzleSitepingStore = class {
|
|
|
486
511
|
* @throws `StoreLimitError` when a `client` comment meets a thread already holding `MAX_COMMENTS_PER_FEEDBACK` of them.
|
|
487
512
|
* @throws `StorePersistenceError` when a database call fails.
|
|
488
513
|
*/
|
|
489
|
-
async addComment(
|
|
514
|
+
async addComment(feedbackId, data) {
|
|
515
|
+
return (await this.addCommentIfAbsent(feedbackId, data)).comment;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* {@link addComment}, reporting whether this call inserted the comment: the
|
|
519
|
+
* single statement inserts at most one row per `clientId`, so of racing
|
|
520
|
+
* posts exactly one reports `created: true`.
|
|
521
|
+
*/
|
|
522
|
+
async addCommentIfAbsent(submittedFeedbackId, submitted) {
|
|
490
523
|
const feedbackId = toStorableText(submittedFeedbackId);
|
|
491
524
|
const data = toStorableValue(submitted);
|
|
492
525
|
const comment = buildCommentRecord(data, { id: crypto.randomUUID(), feedbackId, now: this.now() });
|
|
@@ -507,13 +540,13 @@ var DrizzleSitepingStore = class {
|
|
|
507
540
|
if (feedbackGone) throw new StoreNotFoundError();
|
|
508
541
|
throw error;
|
|
509
542
|
}
|
|
510
|
-
if (inserted) return comment;
|
|
543
|
+
if (inserted) return { comment, created: true };
|
|
511
544
|
const replayed = await persistMutation(
|
|
512
545
|
"addComment",
|
|
513
546
|
identifiers,
|
|
514
547
|
() => this.gateway.findCommentByClientId(data.clientId)
|
|
515
548
|
);
|
|
516
|
-
if (replayed) return replayed;
|
|
549
|
+
if (replayed) return { comment: replayed, created: false };
|
|
517
550
|
const projectName = await persistMutation(
|
|
518
551
|
"addComment",
|
|
519
552
|
identifiers,
|
|
@@ -580,7 +613,8 @@ var DrizzleSitepingStore = class {
|
|
|
580
613
|
});
|
|
581
614
|
return url;
|
|
582
615
|
} catch (error) {
|
|
583
|
-
|
|
616
|
+
warnSafely(
|
|
617
|
+
this.logger,
|
|
584
618
|
"[siteping] DrizzleStore: screenshotStorage.upload failed \u2014 feedback saved without screenshot",
|
|
585
619
|
{ clientId, feedbackId, error }
|
|
586
620
|
);
|
|
@@ -589,7 +623,8 @@ var DrizzleSitepingStore = class {
|
|
|
589
623
|
}
|
|
590
624
|
if (!this.inlineScreenshotWarned) {
|
|
591
625
|
this.inlineScreenshotWarned = true;
|
|
592
|
-
|
|
626
|
+
warnSafely(
|
|
627
|
+
this.logger,
|
|
593
628
|
"[siteping] DrizzleStore: no screenshotStorage configured \u2014 screenshots are stored inline as base64. Configure a ScreenshotStorage for production.",
|
|
594
629
|
{}
|
|
595
630
|
);
|
|
@@ -632,7 +667,8 @@ var DrizzleSitepingStore = class {
|
|
|
632
667
|
try {
|
|
633
668
|
referenced = await this.findReferencedScreenshotUrls(candidates);
|
|
634
669
|
} catch (lookupError) {
|
|
635
|
-
|
|
670
|
+
warnSafely(
|
|
671
|
+
this.logger,
|
|
636
672
|
`${DRIZZLE_STORE_MESSAGE_PREFIX}: screenshot references could not be checked \u2014 screenshots kept`,
|
|
637
673
|
{ ...context, screenshotUrls: candidates, error: lookupError }
|
|
638
674
|
);
|
|
@@ -646,11 +682,15 @@ var DrizzleSitepingStore = class {
|
|
|
646
682
|
);
|
|
647
683
|
results.forEach((result, index) => {
|
|
648
684
|
if (result.status === "rejected") {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
685
|
+
warnSafely(
|
|
686
|
+
this.logger,
|
|
687
|
+
`${DRIZZLE_STORE_MESSAGE_PREFIX}: screenshotStorage.delete failed \u2014 object left in place`,
|
|
688
|
+
{
|
|
689
|
+
...context,
|
|
690
|
+
screenshotUrl: unreferenced[index],
|
|
691
|
+
error: result.reason
|
|
692
|
+
}
|
|
693
|
+
);
|
|
654
694
|
}
|
|
655
695
|
});
|
|
656
696
|
}
|
|
@@ -792,7 +832,12 @@ export {
|
|
|
792
832
|
StoreDuplicateError,
|
|
793
833
|
StorePersistenceError,
|
|
794
834
|
StoreLimitError,
|
|
835
|
+
StoreValueTooLongError,
|
|
836
|
+
isStoreNotFound,
|
|
837
|
+
isStoreDuplicate,
|
|
795
838
|
isStorePersistence,
|
|
839
|
+
isStoreLimit,
|
|
840
|
+
isStoreValueTooLong,
|
|
796
841
|
DRIZZLE_STORE_MESSAGE_PREFIX,
|
|
797
842
|
DrizzleSitepingStore,
|
|
798
843
|
CASE_INSENSITIVE_LIKE_OPERATOR,
|
|
@@ -811,4 +856,4 @@ export {
|
|
|
811
856
|
selectValues,
|
|
812
857
|
monotonicUpdatedAt
|
|
813
858
|
};
|
|
814
|
-
//# sourceMappingURL=chunk-
|
|
859
|
+
//# sourceMappingURL=chunk-6DO75JHR.js.map
|