web-comments 0.0.1 → 0.1.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.
Files changed (53) hide show
  1. package/README.md +188 -6
  2. package/dist/auth/bearer-token.js +43 -0
  3. package/dist/auth/cloudflare-access.js +90 -0
  4. package/dist/auth/dev-user.js +21 -0
  5. package/dist/auth/session-endpoint.js +47 -0
  6. package/dist/chunks/chunk-6VWNCJ3A.js +72 -0
  7. package/dist/chunks/chunk-GHNSLFY2.js +72 -0
  8. package/dist/chunks/chunk-LBIURYPH.js +192 -0
  9. package/dist/chunks/chunk-PLAC65HG.js +71 -0
  10. package/dist/chunks/chunk-WSFCRVEQ.js +9 -0
  11. package/dist/index.js +44 -0
  12. package/dist/react.js +19 -0
  13. package/dist/server.js +501 -0
  14. package/dist/store/d1.js +16 -0
  15. package/dist/store/drizzle/mysql.js +13 -0
  16. package/dist/store/drizzle/pg.js +13 -0
  17. package/dist/store/drizzle/sqlite.js +13 -0
  18. package/dist/store/drizzle.js +10 -0
  19. package/dist/store/memory.js +75 -0
  20. package/dist/store/r2.js +25 -0
  21. package/dist/store/s3.js +43 -0
  22. package/dist/types/auth/bearer-token.d.ts +13 -0
  23. package/dist/types/auth/cloudflare-access.d.ts +33 -0
  24. package/dist/types/auth/dev-user.d.ts +6 -0
  25. package/dist/types/auth/session-endpoint.d.ts +25 -0
  26. package/dist/types/react.d.ts +8 -0
  27. package/dist/types/server/auth.d.ts +16 -0
  28. package/dist/types/server/index.d.ts +71 -0
  29. package/dist/types/server/store.d.ts +59 -0
  30. package/dist/types/server/validate.d.ts +20 -0
  31. package/dist/types/shared/types.d.ts +108 -0
  32. package/dist/types/store/d1.d.ts +9 -0
  33. package/dist/types/store/drizzle/index.d.ts +22 -0
  34. package/dist/types/store/drizzle/mysql.d.ts +506 -0
  35. package/dist/types/store/drizzle/pg.d.ts +476 -0
  36. package/dist/types/store/drizzle/sqlite.d.ts +506 -0
  37. package/dist/types/store/memory.d.ts +10 -0
  38. package/dist/types/store/r2.d.ts +20 -0
  39. package/dist/types/store/s3.d.ts +21 -0
  40. package/dist/types/widget/anchor.d.ts +9 -0
  41. package/dist/types/widget/api.d.ts +43 -0
  42. package/dist/types/widget/app.d.ts +29 -0
  43. package/dist/types/widget/capture.d.ts +33 -0
  44. package/dist/types/widget/format.d.ts +15 -0
  45. package/dist/types/widget/index.d.ts +41 -0
  46. package/dist/types/widget/styles.d.ts +6 -0
  47. package/dist/types/widget/thread.d.ts +32 -0
  48. package/dist/types/widget/tracker.d.ts +68 -0
  49. package/dist/widget.global.js +44 -0
  50. package/package.json +132 -6
  51. package/types/widget.global.d.ts +5 -0
  52. package/index.d.ts +0 -2
  53. package/index.js +0 -6
@@ -0,0 +1,506 @@
1
+ export declare const threads: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
2
+ name: "wc_threads";
3
+ schema: undefined;
4
+ columns: {
5
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
6
+ name: string;
7
+ tableName: "wc_threads";
8
+ dataType: "string";
9
+ data: string;
10
+ driverParam: string;
11
+ notNull: true;
12
+ hasDefault: false;
13
+ isPrimaryKey: true;
14
+ isAutoincrement: false;
15
+ hasRuntimeDefault: false;
16
+ enumValues: [string, ...string[]];
17
+ baseColumn: never;
18
+ identity: undefined;
19
+ generated: undefined;
20
+ }, {}>;
21
+ site: import("drizzle-orm/sqlite-core").SQLiteColumn<{
22
+ name: string;
23
+ tableName: "wc_threads";
24
+ dataType: "string";
25
+ data: string;
26
+ driverParam: string;
27
+ notNull: true;
28
+ hasDefault: false;
29
+ isPrimaryKey: false;
30
+ isAutoincrement: false;
31
+ hasRuntimeDefault: false;
32
+ enumValues: [string, ...string[]];
33
+ baseColumn: never;
34
+ identity: undefined;
35
+ generated: undefined;
36
+ }, {}>;
37
+ page: import("drizzle-orm/sqlite-core").SQLiteColumn<{
38
+ name: string;
39
+ tableName: "wc_threads";
40
+ dataType: "string";
41
+ data: string;
42
+ driverParam: string;
43
+ notNull: true;
44
+ hasDefault: false;
45
+ isPrimaryKey: false;
46
+ isAutoincrement: false;
47
+ hasRuntimeDefault: false;
48
+ enumValues: [string, ...string[]];
49
+ baseColumn: never;
50
+ identity: undefined;
51
+ generated: undefined;
52
+ }, {}>;
53
+ url: import("drizzle-orm/sqlite-core").SQLiteColumn<{
54
+ name: string;
55
+ tableName: "wc_threads";
56
+ dataType: "string";
57
+ data: string;
58
+ driverParam: string;
59
+ notNull: true;
60
+ hasDefault: false;
61
+ isPrimaryKey: false;
62
+ isAutoincrement: false;
63
+ hasRuntimeDefault: false;
64
+ enumValues: [string, ...string[]];
65
+ baseColumn: never;
66
+ identity: undefined;
67
+ generated: undefined;
68
+ }, {}>;
69
+ anchor: import("drizzle-orm/sqlite-core").SQLiteColumn<{
70
+ name: string;
71
+ tableName: "wc_threads";
72
+ dataType: "string";
73
+ data: string;
74
+ driverParam: string;
75
+ notNull: true;
76
+ hasDefault: false;
77
+ isPrimaryKey: false;
78
+ isAutoincrement: false;
79
+ hasRuntimeDefault: false;
80
+ enumValues: [string, ...string[]];
81
+ baseColumn: never;
82
+ identity: undefined;
83
+ generated: undefined;
84
+ }, {}>;
85
+ context: import("drizzle-orm/sqlite-core").SQLiteColumn<{
86
+ name: string;
87
+ tableName: "wc_threads";
88
+ dataType: "string";
89
+ data: string;
90
+ driverParam: string;
91
+ notNull: false;
92
+ hasDefault: false;
93
+ isPrimaryKey: false;
94
+ isAutoincrement: false;
95
+ hasRuntimeDefault: false;
96
+ enumValues: [string, ...string[]];
97
+ baseColumn: never;
98
+ identity: undefined;
99
+ generated: undefined;
100
+ }, {}>;
101
+ screenshots: import("drizzle-orm/sqlite-core").SQLiteColumn<{
102
+ name: string;
103
+ tableName: "wc_threads";
104
+ dataType: "string";
105
+ data: string;
106
+ driverParam: string;
107
+ notNull: true;
108
+ hasDefault: false;
109
+ isPrimaryKey: false;
110
+ isAutoincrement: false;
111
+ hasRuntimeDefault: false;
112
+ enumValues: [string, ...string[]];
113
+ baseColumn: never;
114
+ identity: undefined;
115
+ generated: undefined;
116
+ }, {}>;
117
+ status: import("drizzle-orm/sqlite-core").SQLiteColumn<{
118
+ name: string;
119
+ tableName: "wc_threads";
120
+ dataType: "string";
121
+ data: string;
122
+ driverParam: string;
123
+ notNull: true;
124
+ hasDefault: false;
125
+ isPrimaryKey: false;
126
+ isAutoincrement: false;
127
+ hasRuntimeDefault: false;
128
+ enumValues: [string, ...string[]];
129
+ baseColumn: never;
130
+ identity: undefined;
131
+ generated: undefined;
132
+ }, {}>;
133
+ authorId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
134
+ name: string;
135
+ tableName: "wc_threads";
136
+ dataType: "string";
137
+ data: string;
138
+ driverParam: string;
139
+ notNull: true;
140
+ hasDefault: false;
141
+ isPrimaryKey: false;
142
+ isAutoincrement: false;
143
+ hasRuntimeDefault: false;
144
+ enumValues: [string, ...string[]];
145
+ baseColumn: never;
146
+ identity: undefined;
147
+ generated: undefined;
148
+ }, {}>;
149
+ authorName: import("drizzle-orm/sqlite-core").SQLiteColumn<{
150
+ name: string;
151
+ tableName: "wc_threads";
152
+ dataType: "string";
153
+ data: string;
154
+ driverParam: string;
155
+ notNull: true;
156
+ hasDefault: false;
157
+ isPrimaryKey: false;
158
+ isAutoincrement: false;
159
+ hasRuntimeDefault: false;
160
+ enumValues: [string, ...string[]];
161
+ baseColumn: never;
162
+ identity: undefined;
163
+ generated: undefined;
164
+ }, {}>;
165
+ authorAvatar: import("drizzle-orm/sqlite-core").SQLiteColumn<{
166
+ name: string;
167
+ tableName: "wc_threads";
168
+ dataType: "string";
169
+ data: string;
170
+ driverParam: string;
171
+ notNull: false;
172
+ hasDefault: false;
173
+ isPrimaryKey: false;
174
+ isAutoincrement: false;
175
+ hasRuntimeDefault: false;
176
+ enumValues: [string, ...string[]];
177
+ baseColumn: never;
178
+ identity: undefined;
179
+ generated: undefined;
180
+ }, {}>;
181
+ authorKind: import("drizzle-orm/sqlite-core").SQLiteColumn<{
182
+ name: string;
183
+ tableName: "wc_threads";
184
+ dataType: "string";
185
+ data: string;
186
+ driverParam: string;
187
+ notNull: true;
188
+ hasDefault: false;
189
+ isPrimaryKey: false;
190
+ isAutoincrement: false;
191
+ hasRuntimeDefault: false;
192
+ enumValues: [string, ...string[]];
193
+ baseColumn: never;
194
+ identity: undefined;
195
+ generated: undefined;
196
+ }, {}>;
197
+ createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
198
+ name: string;
199
+ tableName: "wc_threads";
200
+ dataType: "string";
201
+ data: string;
202
+ driverParam: string;
203
+ notNull: true;
204
+ hasDefault: false;
205
+ isPrimaryKey: false;
206
+ isAutoincrement: false;
207
+ hasRuntimeDefault: false;
208
+ enumValues: [string, ...string[]];
209
+ baseColumn: never;
210
+ identity: undefined;
211
+ generated: undefined;
212
+ }, {}>;
213
+ updatedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
214
+ name: string;
215
+ tableName: "wc_threads";
216
+ dataType: "string";
217
+ data: string;
218
+ driverParam: string;
219
+ notNull: true;
220
+ hasDefault: false;
221
+ isPrimaryKey: false;
222
+ isAutoincrement: false;
223
+ hasRuntimeDefault: false;
224
+ enumValues: [string, ...string[]];
225
+ baseColumn: never;
226
+ identity: undefined;
227
+ generated: undefined;
228
+ }, {}>;
229
+ resolvedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
230
+ name: string;
231
+ tableName: "wc_threads";
232
+ dataType: "string";
233
+ data: string;
234
+ driverParam: string;
235
+ notNull: false;
236
+ hasDefault: false;
237
+ isPrimaryKey: false;
238
+ isAutoincrement: false;
239
+ hasRuntimeDefault: false;
240
+ enumValues: [string, ...string[]];
241
+ baseColumn: never;
242
+ identity: undefined;
243
+ generated: undefined;
244
+ }, {}>;
245
+ resolvedBy: import("drizzle-orm/sqlite-core").SQLiteColumn<{
246
+ name: string;
247
+ tableName: "wc_threads";
248
+ dataType: "string";
249
+ data: string;
250
+ driverParam: string;
251
+ notNull: false;
252
+ hasDefault: false;
253
+ isPrimaryKey: false;
254
+ isAutoincrement: false;
255
+ hasRuntimeDefault: false;
256
+ enumValues: [string, ...string[]];
257
+ baseColumn: never;
258
+ identity: undefined;
259
+ generated: undefined;
260
+ }, {}>;
261
+ };
262
+ dialect: 'sqlite';
263
+ isAlias: false;
264
+ }>;
265
+ export declare const comments: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
266
+ name: "wc_comments";
267
+ schema: undefined;
268
+ columns: {
269
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
270
+ name: string;
271
+ tableName: "wc_comments";
272
+ dataType: "string";
273
+ data: string;
274
+ driverParam: string;
275
+ notNull: true;
276
+ hasDefault: false;
277
+ isPrimaryKey: true;
278
+ isAutoincrement: false;
279
+ hasRuntimeDefault: false;
280
+ enumValues: [string, ...string[]];
281
+ baseColumn: never;
282
+ identity: undefined;
283
+ generated: undefined;
284
+ }, {}>;
285
+ threadId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
286
+ name: string;
287
+ tableName: "wc_comments";
288
+ dataType: "string";
289
+ data: string;
290
+ driverParam: string;
291
+ notNull: true;
292
+ hasDefault: false;
293
+ isPrimaryKey: false;
294
+ isAutoincrement: false;
295
+ hasRuntimeDefault: false;
296
+ enumValues: [string, ...string[]];
297
+ baseColumn: never;
298
+ identity: undefined;
299
+ generated: undefined;
300
+ }, {}>;
301
+ body: import("drizzle-orm/sqlite-core").SQLiteColumn<{
302
+ name: string;
303
+ tableName: "wc_comments";
304
+ dataType: "string";
305
+ data: string;
306
+ driverParam: string;
307
+ notNull: true;
308
+ hasDefault: false;
309
+ isPrimaryKey: false;
310
+ isAutoincrement: false;
311
+ hasRuntimeDefault: false;
312
+ enumValues: [string, ...string[]];
313
+ baseColumn: never;
314
+ identity: undefined;
315
+ generated: undefined;
316
+ }, {}>;
317
+ authorId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
318
+ name: string;
319
+ tableName: "wc_comments";
320
+ dataType: "string";
321
+ data: string;
322
+ driverParam: string;
323
+ notNull: true;
324
+ hasDefault: false;
325
+ isPrimaryKey: false;
326
+ isAutoincrement: false;
327
+ hasRuntimeDefault: false;
328
+ enumValues: [string, ...string[]];
329
+ baseColumn: never;
330
+ identity: undefined;
331
+ generated: undefined;
332
+ }, {}>;
333
+ authorName: import("drizzle-orm/sqlite-core").SQLiteColumn<{
334
+ name: string;
335
+ tableName: "wc_comments";
336
+ dataType: "string";
337
+ data: string;
338
+ driverParam: string;
339
+ notNull: true;
340
+ hasDefault: false;
341
+ isPrimaryKey: false;
342
+ isAutoincrement: false;
343
+ hasRuntimeDefault: false;
344
+ enumValues: [string, ...string[]];
345
+ baseColumn: never;
346
+ identity: undefined;
347
+ generated: undefined;
348
+ }, {}>;
349
+ authorAvatar: import("drizzle-orm/sqlite-core").SQLiteColumn<{
350
+ name: string;
351
+ tableName: "wc_comments";
352
+ dataType: "string";
353
+ data: string;
354
+ driverParam: string;
355
+ notNull: false;
356
+ hasDefault: false;
357
+ isPrimaryKey: false;
358
+ isAutoincrement: false;
359
+ hasRuntimeDefault: false;
360
+ enumValues: [string, ...string[]];
361
+ baseColumn: never;
362
+ identity: undefined;
363
+ generated: undefined;
364
+ }, {}>;
365
+ authorKind: import("drizzle-orm/sqlite-core").SQLiteColumn<{
366
+ name: string;
367
+ tableName: "wc_comments";
368
+ dataType: "string";
369
+ data: string;
370
+ driverParam: string;
371
+ notNull: true;
372
+ hasDefault: false;
373
+ isPrimaryKey: false;
374
+ isAutoincrement: false;
375
+ hasRuntimeDefault: false;
376
+ enumValues: [string, ...string[]];
377
+ baseColumn: never;
378
+ identity: undefined;
379
+ generated: undefined;
380
+ }, {}>;
381
+ createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
382
+ name: string;
383
+ tableName: "wc_comments";
384
+ dataType: "string";
385
+ data: string;
386
+ driverParam: string;
387
+ notNull: true;
388
+ hasDefault: false;
389
+ isPrimaryKey: false;
390
+ isAutoincrement: false;
391
+ hasRuntimeDefault: false;
392
+ enumValues: [string, ...string[]];
393
+ baseColumn: never;
394
+ identity: undefined;
395
+ generated: undefined;
396
+ }, {}>;
397
+ };
398
+ dialect: 'sqlite';
399
+ isAlias: false;
400
+ }>;
401
+ export declare const users: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
402
+ name: "wc_users";
403
+ schema: undefined;
404
+ columns: {
405
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
406
+ name: string;
407
+ tableName: "wc_users";
408
+ dataType: "string";
409
+ data: string;
410
+ driverParam: string;
411
+ notNull: true;
412
+ hasDefault: false;
413
+ isPrimaryKey: true;
414
+ isAutoincrement: false;
415
+ hasRuntimeDefault: false;
416
+ enumValues: [string, ...string[]];
417
+ baseColumn: never;
418
+ identity: undefined;
419
+ generated: undefined;
420
+ }, {}>;
421
+ name: import("drizzle-orm/sqlite-core").SQLiteColumn<{
422
+ name: string;
423
+ tableName: "wc_users";
424
+ dataType: "string";
425
+ data: string;
426
+ driverParam: string;
427
+ notNull: true;
428
+ hasDefault: false;
429
+ isPrimaryKey: false;
430
+ isAutoincrement: false;
431
+ hasRuntimeDefault: false;
432
+ enumValues: [string, ...string[]];
433
+ baseColumn: never;
434
+ identity: undefined;
435
+ generated: undefined;
436
+ }, {}>;
437
+ email: import("drizzle-orm/sqlite-core").SQLiteColumn<{
438
+ name: string;
439
+ tableName: "wc_users";
440
+ dataType: "string";
441
+ data: string;
442
+ driverParam: string;
443
+ notNull: false;
444
+ hasDefault: false;
445
+ isPrimaryKey: false;
446
+ isAutoincrement: false;
447
+ hasRuntimeDefault: false;
448
+ enumValues: [string, ...string[]];
449
+ baseColumn: never;
450
+ identity: undefined;
451
+ generated: undefined;
452
+ }, {}>;
453
+ avatarUrl: import("drizzle-orm/sqlite-core").SQLiteColumn<{
454
+ name: string;
455
+ tableName: "wc_users";
456
+ dataType: "string";
457
+ data: string;
458
+ driverParam: string;
459
+ notNull: false;
460
+ hasDefault: false;
461
+ isPrimaryKey: false;
462
+ isAutoincrement: false;
463
+ hasRuntimeDefault: false;
464
+ enumValues: [string, ...string[]];
465
+ baseColumn: never;
466
+ identity: undefined;
467
+ generated: undefined;
468
+ }, {}>;
469
+ kind: import("drizzle-orm/sqlite-core").SQLiteColumn<{
470
+ name: string;
471
+ tableName: "wc_users";
472
+ dataType: "string";
473
+ data: string;
474
+ driverParam: string;
475
+ notNull: true;
476
+ hasDefault: false;
477
+ isPrimaryKey: false;
478
+ isAutoincrement: false;
479
+ hasRuntimeDefault: false;
480
+ enumValues: [string, ...string[]];
481
+ baseColumn: never;
482
+ identity: undefined;
483
+ generated: undefined;
484
+ }, {}>;
485
+ lastSeenAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
486
+ name: string;
487
+ tableName: "wc_users";
488
+ dataType: "string";
489
+ data: string;
490
+ driverParam: string;
491
+ notNull: true;
492
+ hasDefault: false;
493
+ isPrimaryKey: false;
494
+ isAutoincrement: false;
495
+ hasRuntimeDefault: false;
496
+ enumValues: [string, ...string[]];
497
+ baseColumn: never;
498
+ identity: undefined;
499
+ generated: undefined;
500
+ }, {}>;
501
+ };
502
+ dialect: 'sqlite';
503
+ isAlias: false;
504
+ }>;
505
+ /** The same tables as SQL, each statement safe to run again. */
506
+ export declare const createTablesSql: string[];
@@ -0,0 +1,10 @@
1
+ import type { AssetStore, CommentsStore } from "../server/store";
2
+ /**
3
+ * Keeps everything in memory: for tests and trying things out, and the
4
+ * smallest example of a CommentsStore. Gone when the process ends.
5
+ */
6
+ export declare function memoryStore(): CommentsStore;
7
+ /** Keeps screenshots in memory, for tests. */
8
+ export declare function memoryAssets(): AssetStore & {
9
+ size(): number;
10
+ };
@@ -0,0 +1,20 @@
1
+ import type { AssetStore } from "../server/store";
2
+ /** The slice of a Workers R2 binding this uses. */
3
+ export interface R2BucketLike {
4
+ put(key: string, value: ArrayBuffer, options?: {
5
+ httpMetadata?: {
6
+ contentType?: string;
7
+ };
8
+ }): Promise<unknown>;
9
+ get(key: string): Promise<{
10
+ body: ReadableStream;
11
+ httpMetadata?: {
12
+ contentType?: string;
13
+ };
14
+ } | null>;
15
+ delete(key: string): Promise<void>;
16
+ }
17
+ /** Screenshots in a Cloudflare R2 bucket, through its Workers binding: `assets: (env) => r2Assets(env.SCREENSHOTS)`. */
18
+ export declare function r2Assets(bucket: R2BucketLike, options?: {
19
+ prefix?: string;
20
+ }): AssetStore;
@@ -0,0 +1,21 @@
1
+ import type { AssetStore } from "../server/store";
2
+ export interface S3AssetsOptions {
3
+ /**
4
+ * The S3 API endpoint, without the bucket: "https://s3.us-east-1.amazonaws.com",
5
+ * "https://<account>.r2.cloudflarestorage.com", a MinIO URL, ...
6
+ */
7
+ endpoint: string;
8
+ bucket: string;
9
+ accessKeyId: string;
10
+ secretAccessKey: string;
11
+ /** Default "auto", which R2 expects; AWS needs the bucket's region. */
12
+ region?: string;
13
+ /** Put every key under this prefix, e.g. "web-comments/". */
14
+ prefix?: string;
15
+ }
16
+ /**
17
+ * Screenshots in any S3-compatible bucket (AWS S3, R2's S3 API, MinIO, ...),
18
+ * signed with SigV4 over fetch, so it runs on Workers, Node and Bun alike.
19
+ * Path-style addressing: {endpoint}/{bucket}/{key}.
20
+ */
21
+ export declare function s3Assets(options: S3AssetsOptions): AssetStore;
@@ -0,0 +1,9 @@
1
+ import type { Anchor } from "../shared/types";
2
+ export declare function textOf(element: Element): string;
3
+ /** The page element under a point, looking past the widget's own layer. */
4
+ export declare function elementAt(x: number, y: number, host: Element): Element | null;
5
+ /** Describes where a click landed so the comment can find its element again later. */
6
+ export declare function createAnchor(element: Element, clientX: number, clientY: number): Anchor;
7
+ /** Finds an anchor's element on the page as it is now, or null when it's gone. */
8
+ export declare function resolveAnchor(anchor: Anchor): Element | null;
9
+ export declare function selectorFor(element: Element): string;
@@ -0,0 +1,43 @@
1
+ import type { Anchor, Identity, Thread, ThreadContext, ThreadStatus } from "../shared/types";
2
+ import type { Shots } from "./capture";
3
+ export interface ApiOptions {
4
+ endpoint: string;
5
+ headers?: () => Record<string, string> | Promise<Record<string, string>>;
6
+ credentials: RequestCredentials;
7
+ }
8
+ /** The API answered that nobody is signed in (or the gate in front of it did). */
9
+ export declare class SignedOut extends Error {
10
+ readonly loginUrl?: string | undefined;
11
+ constructor(loginUrl?: string | undefined);
12
+ }
13
+ /** Signed in, but not allowed to use comments here. */
14
+ export declare class Forbidden extends Error {
15
+ }
16
+ export declare class ApiError extends Error {
17
+ readonly status: number;
18
+ constructor(message: string, status: number);
19
+ }
20
+ export declare function createApi(options: ApiOptions): {
21
+ /** A path the API returned (a screenshot), as a URL the browser can load: it's relative to the API's host. */
22
+ resolve: (path: string) => string;
23
+ me: () => Promise<Identity>;
24
+ threads: (page: string) => Promise<Thread[]>;
25
+ thread: (threadId: string) => Promise<Thread>;
26
+ /** Opens a thread, sending its screenshots along in the same request when there are any. */
27
+ createThread: (input: {
28
+ page: string;
29
+ url: string;
30
+ anchor: Anchor;
31
+ context?: ThreadContext;
32
+ body: string;
33
+ }, shots?: Shots) => Promise<Thread>;
34
+ reply: (threadId: string, body: string) => Promise<Thread>;
35
+ /** Moves a thread's pin to a new spot on the page. Only its author may. */
36
+ moveThread: (threadId: string, anchor: Anchor) => Promise<Thread>;
37
+ setStatus: (threadId: string, status: ThreadStatus) => Promise<Thread>;
38
+ deleteComment: (commentId: string) => Promise<{
39
+ deleted: "comment" | "thread";
40
+ threadId: string;
41
+ }>;
42
+ };
43
+ export type Api = ReturnType<typeof createApi>;
@@ -0,0 +1,29 @@
1
+ import { type Api } from "./api";
2
+ import { type Tracker } from "./tracker";
3
+ export interface Settings {
4
+ page: () => string;
5
+ shortcut: string | false;
6
+ pollInterval: number;
7
+ linkParam: string;
8
+ /** "push" moves the page over to make room for the toolbar; "overlay" draws it on top. */
9
+ dock: "push" | "overlay";
10
+ }
11
+ /** What mountComments hands back, wired up once the app is running. */
12
+ export interface Controls {
13
+ open?: (threadId: string) => void;
14
+ setPlacing?: (placing: boolean) => void;
15
+ }
16
+ interface RootProps {
17
+ api: Api;
18
+ host: HTMLElement;
19
+ tracker: Tracker;
20
+ settings: Settings;
21
+ controls: Controls;
22
+ colorScheme: "light" | "dark" | undefined;
23
+ zIndex: number;
24
+ }
25
+ /** Spectrum's Provider, with overlays (menus, tooltips, dialogs) kept inside the shadow root. */
26
+ export declare function Root({ colorScheme, zIndex, ...props }: RootProps): import("react").JSX.Element;
27
+ type AppProps = Omit<RootProps, "colorScheme" | "zIndex">;
28
+ export declare function App({ api, host, tracker, settings, controls }: AppProps): import("react").JSX.Element | null;
29
+ export {};
@@ -0,0 +1,33 @@
1
+ import type { ScreenshotKind, ThreadContext } from "../shared/types";
2
+ export interface Shot {
3
+ blob: Blob;
4
+ width: number;
5
+ height: number;
6
+ }
7
+ export type Shots = Partial<Record<ScreenshotKind, Shot>>;
8
+ /** What the commenter is looking at: the element and the page around it. */
9
+ export declare function contextOf(element: Element): ThreadContext;
10
+ /**
11
+ * Two screenshots from one render of the viewport, drawn from the DOM and
12
+ * leaving the widget out: the viewport as it was, and the element in its
13
+ * surroundings with an outline round it. None comes back when the page can't
14
+ * be drawn (a render that times out); a comment never waits on them for long.
15
+ */
16
+ export declare function capture(element: Element, host: Element): Promise<Shots>;
17
+ /** The part of the viewport to show for an element: it, a margin, at least a minimum size, inside the viewport. */
18
+ export declare function cropAround(rect: {
19
+ x: number;
20
+ y: number;
21
+ width: number;
22
+ height: number;
23
+ }, viewport: {
24
+ width: number;
25
+ height: number;
26
+ }): {
27
+ x: number;
28
+ y: number;
29
+ width: number;
30
+ height: number;
31
+ };
32
+ /** Waits for screenshots, but never longer than `ms`: a comment goes out without them rather than late. */
33
+ export declare function within(shots: Promise<Shots>, ms: number): Promise<Shots>;
@@ -0,0 +1,15 @@
1
+ export declare function colorFor(id: string): string;
2
+ /** An image for Spectrum's Avatar: the person's picture, or their initials on a color. */
3
+ export declare function avatarSrc(person: {
4
+ id: string;
5
+ name: string;
6
+ avatarUrl?: string;
7
+ }): string;
8
+ /** "Ada Lovelace" → "AL", "林黛玉" → "林" */
9
+ export declare function initials(name: string): string;
10
+ export declare function timeAgo(iso: string, now: number): string;
11
+ /** Splits text into plain strings and links (with where each starts), for rendering without innerHTML. */
12
+ export declare function linkify(text: string): Array<string | {
13
+ href: string;
14
+ start: number;
15
+ }>;