@growth-labs/cms 0.2.0 → 0.3.1

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 (49) hide show
  1. package/README.md +106 -2
  2. package/dist/cli/migrations.d.ts +3 -0
  3. package/dist/cli/migrations.d.ts.map +1 -0
  4. package/dist/cli/migrations.js +73 -0
  5. package/dist/cli/migrations.js.map +1 -0
  6. package/dist/engine/index.d.ts +1 -0
  7. package/dist/engine/index.d.ts.map +1 -1
  8. package/dist/engine/index.js +2 -0
  9. package/dist/engine/index.js.map +1 -1
  10. package/dist/engine/reader-state.d.ts +127 -0
  11. package/dist/engine/reader-state.d.ts.map +1 -0
  12. package/dist/engine/reader-state.js +493 -0
  13. package/dist/engine/reader-state.js.map +1 -0
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/migration-vendor-files.d.ts +17 -0
  19. package/dist/migration-vendor-files.d.ts.map +1 -0
  20. package/dist/migration-vendor-files.js +67 -0
  21. package/dist/migration-vendor-files.js.map +1 -0
  22. package/dist/migration-vendor.d.ts +26 -0
  23. package/dist/migration-vendor.d.ts.map +1 -0
  24. package/dist/migration-vendor.js +321 -0
  25. package/dist/migration-vendor.js.map +1 -0
  26. package/dist/schema/index.d.ts +1 -1
  27. package/dist/schema/index.d.ts.map +1 -1
  28. package/dist/schema/migrations.d.ts.map +1 -1
  29. package/dist/schema/migrations.js +37 -0
  30. package/dist/schema/migrations.js.map +1 -1
  31. package/dist/schema/tables.d.ts +1 -1
  32. package/dist/schema/tables.d.ts.map +1 -1
  33. package/dist/schema/tables.js +5 -2
  34. package/dist/schema/tables.js.map +1 -1
  35. package/dist/schema/types.d.ts +27 -0
  36. package/dist/schema/types.d.ts.map +1 -1
  37. package/dist/schema/types.js.map +1 -1
  38. package/migrations/0019_reader_state.sql +34 -0
  39. package/package.json +8 -1
  40. package/src/cli/migrations.ts +85 -0
  41. package/src/engine/index.ts +38 -0
  42. package/src/engine/reader-state.ts +918 -0
  43. package/src/index.ts +4 -2
  44. package/src/migration-vendor-files.ts +100 -0
  45. package/src/migration-vendor.ts +450 -0
  46. package/src/schema/index.ts +2 -0
  47. package/src/schema/migrations.ts +37 -0
  48. package/src/schema/tables.ts +5 -2
  49. package/src/schema/types.ts +29 -0
package/README.md CHANGED
@@ -168,6 +168,49 @@ manual publish with a 409 and leaves the content status unchanged; throwing from
168
168
  the hook fails closed with a 503. This keeps media-specific readiness checks in
169
169
  the host site while preventing a configured site from bypassing them.
170
170
 
171
+ ## Consumer D1 migrations
172
+
173
+ Wrangler accepts one `migrations_dir`, while a site commonly already owns
174
+ numbered analytics, SEO, or product migrations. Vendor the exact SQL from the
175
+ installed CMS package into that existing directory, review it, and commit it:
176
+
177
+ ```bash
178
+ pnpm exec growth-labs-cms-migrations sync --dir migrations --start 10
179
+ pnpm exec growth-labs-cms-migrations verify --dir migrations
180
+ ```
181
+
182
+ `--start` is the first unused site sequence and is mandatory. `sync` reserves a
183
+ contiguous range, copies every package migration without rewriting it, and writes
184
+ `migrations/.growth-labs-cms-migrations.json` with the package version and SHA-256
185
+ receipt. It fails before writing if any site SQL already owns a reserved sequence.
186
+ Existing managed SQL is never overwritten: consumer drift, upstream mutation of
187
+ an already-vendored migration, a changed starting sequence, or a symlink target
188
+ fails closed.
189
+
190
+ The default receipt path is the only manifest allowed inside `migrations/`.
191
+ When `--manifest` is supplied, it must name a `.json` file outside the migrations
192
+ directory whose parent is an existing non-symlink directory; it can never
193
+ collide with or become Wrangler SQL. Sync stages the full SQL set and receipt
194
+ before linking targets. A later link, verification, or receipt failure removes
195
+ every SQL file created by that attempt. An interrupted process may leave only
196
+ exact-hash linked SQL and/or `*.tmp-<uuid>` staging files, but no valid completed
197
+ receipt; `verify` therefore fails closed until a repeated `sync` reconciles the
198
+ batch. Wrangler ignores the temp files, which are safe to delete after the
199
+ repeated sync and verify succeed. Never run the managed D1 workflow without the
200
+ required verify step.
201
+
202
+ Both `sync` and `verify` acquire an exclusive adjacent `<receipt>.lock` file,
203
+ so concurrent invocations fail closed instead of racing the manifest update.
204
+ An abruptly terminated process can leave a stale lock; first confirm no vendor
205
+ or verify process is running, then remove only that lock and repeat `sync`
206
+ followed by `verify`.
207
+
208
+ Run `sync` deliberately after a package upgrade, inspect and commit the new SQL
209
+ and receipt, then require `verify` in pull-request CI before the managed D1
210
+ migration workflow. The command only reads and writes local files; it never opens
211
+ a network connection or applies a database migration. Do not call schema setup
212
+ from a request handler.
213
+
171
214
  ## Bounded publication kernel
172
215
 
173
216
  `publishOne` is the build-independent publication path for a single content item.
@@ -211,14 +254,14 @@ const receipt = await publishOne(env.SITE_DB, {
211
254
  feedReconciler,
212
255
  searchReconciler,
213
256
  ],
214
- packageVersion: '0.2.0',
257
+ packageVersion: '0.3.0',
215
258
  })
216
259
 
217
260
  await rollbackPublication(env.SITE_DB, {
218
261
  contentId,
219
262
  targetRevisionId: priorRevisionId,
220
263
  surfaces: [sitemapReconciler, feedReconciler, searchReconciler],
221
- packageVersion: '0.1.2',
264
+ packageVersion: '0.2.0',
222
265
  })
223
266
  ```
224
267
 
@@ -314,6 +357,67 @@ representative body/taxonomy distributions and records local Miniflare evidence
314
357
  as local CPU/memory only; live D1/R2 latency remains a separate controlled
315
358
  Worker measurement.
316
359
 
360
+ ## Reader state and privacy
361
+
362
+ Apply migration `0019_reader_state` before adopting the reader-state API. The
363
+ consumer supplies a scope only after verifying both the realm user and site
364
+ token. `identityUserId` is the raw issuer UUID/ULID; prefixed subjects, email or
365
+ local IDs, and 64-hex analytics IDs are rejected. Content is always addressed by
366
+ its stable CMS ID plus content type, never by slug.
367
+
368
+ ```typescript
369
+ import {
370
+ clearReaderHistory,
371
+ exportReaderStatePage,
372
+ recordReaderOpen,
373
+ recordReaderProgress,
374
+ setManualReadState,
375
+ setSavedState,
376
+ } from '@growth-labs/cms'
377
+
378
+ const scope = { identityUserId: verifiedRawUserId, siteId: verifiedSiteId }
379
+ const content = { contentType: 'article', contentId: stableContentId }
380
+
381
+ await recordReaderOpen(env.SITE_DB, scope, content, {
382
+ behavioralConsent: consent.readerHistory ? 'granted' : 'denied',
383
+ })
384
+ await recordReaderProgress(env.SITE_DB, scope, content, {
385
+ behavioralConsent: consent.readerHistory ? 'granted' : 'denied',
386
+ progressBasisPoints: 9_000,
387
+ })
388
+ await setManualReadState(env.SITE_DB, scope, content, {
389
+ state: 'unread',
390
+ occurredAt: eventTime,
391
+ mutationId: idempotencyKey,
392
+ })
393
+ await setSavedState(env.SITE_DB, scope, content, {
394
+ saved: true,
395
+ occurredAt: eventTime,
396
+ mutationId: idempotencyKey,
397
+ })
398
+
399
+ const page = await exportReaderStatePage(env.SITE_DB, scope, { limit: 100 })
400
+ await clearReaderHistory(env.SITE_DB, scope)
401
+ ```
402
+
403
+ Progress is monotonic and reaches automatic completion at 90 percent. A manual
404
+ read/unread value overrides automatic completion until explicitly cleared.
405
+ Explicit mutations use event time plus `mutationId` for deterministic ordering
406
+ and may supply `expectedVersion` for compare-and-swap. Batch/list/export reads
407
+ are limited to 100 rows and remain inside one verified user/site scope. List
408
+ cursors order by last update; export cursors are a distinct opaque type ordered
409
+ by immutable row creation time so concurrent activity cannot move an existing
410
+ row across an export page boundary. Consent
411
+ withdrawal clears behavioral history while retaining explicit manual, saved,
412
+ and stated-preference choices; `deleteReaderState` erases the entire current
413
+ user/site scope. Network-wide erasure is intentionally orchestrated by invoking
414
+ that site-scoped operation under each separately verified site authority.
415
+
416
+ Rollback is additive and data-preserving: pin `@growth-labs/cms@0.2.0` and stop
417
+ calling the reader-state surface, but leave `cms_reader_state` and migration
418
+ `0019` in place. Re-adopting `0.3.0` resumes from the preserved rows; rollback
419
+ must never drop or reinterpret them through analytics identity.
420
+
317
421
  ## Coming in later waves
318
422
 
319
423
  - Broader admin UI polish and per-site extension points beyond the shipped
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=migrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/cli/migrations.ts"],"names":[],"mappings":""}
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+ import { syncCmsMigrations, verifyCmsMigrations } from '../migration-vendor.js';
3
+ function usage() {
4
+ return [
5
+ 'Usage:',
6
+ ' growth-labs-cms-migrations sync --dir <migrations-dir> --start <positive-integer>',
7
+ ' growth-labs-cms-migrations verify --dir <migrations-dir>',
8
+ '',
9
+ 'Optional for both commands: --manifest <receipt-path>',
10
+ ].join('\n');
11
+ }
12
+ function requireValue(argv, index, flag) {
13
+ const value = argv[index + 1];
14
+ if (!value || value.startsWith('--'))
15
+ throw new Error(`${flag} requires a value`);
16
+ return value;
17
+ }
18
+ function parseArgs(argv) {
19
+ const command = argv[0];
20
+ if (command !== 'sync' && command !== 'verify')
21
+ throw new Error(usage());
22
+ let migrationsDir;
23
+ let startSequence;
24
+ let manifestPath;
25
+ for (let index = 1; index < argv.length; index += 1) {
26
+ const flag = argv[index];
27
+ if (flag === '--dir') {
28
+ migrationsDir = requireValue(argv, index, flag);
29
+ index += 1;
30
+ continue;
31
+ }
32
+ if (flag === '--start') {
33
+ startSequence = Number(requireValue(argv, index, flag));
34
+ index += 1;
35
+ continue;
36
+ }
37
+ if (flag === '--manifest') {
38
+ manifestPath = requireValue(argv, index, flag);
39
+ index += 1;
40
+ continue;
41
+ }
42
+ throw new Error(`unknown argument: ${flag}\n\n${usage()}`);
43
+ }
44
+ if (!migrationsDir)
45
+ throw new Error(`--dir is required\n\n${usage()}`);
46
+ if (command === 'sync' && startSequence === undefined) {
47
+ throw new Error(`--start is required for sync\n\n${usage()}`);
48
+ }
49
+ if (command === 'verify' && startSequence !== undefined) {
50
+ throw new Error('--start is read from the committed manifest during verify');
51
+ }
52
+ return { command, migrationsDir, startSequence, manifestPath };
53
+ }
54
+ async function main() {
55
+ const args = parseArgs(process.argv.slice(2));
56
+ const result = args.command === 'sync'
57
+ ? await syncCmsMigrations({
58
+ migrationsDir: args.migrationsDir,
59
+ startSequence: args.startSequence,
60
+ manifestPath: args.manifestPath,
61
+ })
62
+ : await verifyCmsMigrations({
63
+ migrationsDir: args.migrationsDir,
64
+ manifestPath: args.manifestPath,
65
+ });
66
+ process.stdout.write(`${JSON.stringify({ ok: true, command: args.command, ...result })}\n`);
67
+ }
68
+ main().catch((error) => {
69
+ const message = error instanceof Error ? error.message : String(error);
70
+ process.stderr.write(`growth-labs-cms-migrations: ${message}\n`);
71
+ process.exitCode = 1;
72
+ });
73
+ //# sourceMappingURL=migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/cli/migrations.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ export { buildOgCardSpec, type OgCardSpec, type OgCardSpecOpts, type OgImageRend
14
14
  export { ContentArchiveImportLimitError, type ContentArchiveInput, type ContentArchiveItem, DEFAULT_PENDING_PUBLICATION_ATTEMPT_LIMIT, DEFAULT_PUBLICATION_SURFACE_HOOK_TIMEOUT_MS, type ImportContentArchiveOptions, type ImportContentArchiveResult, type ImportedArchiveItem, importContentArchive, type ListPendingPublicationAttemptsOptions, listPendingPublicationAttempts, MAX_PENDING_PUBLICATION_ATTEMPT_LIMIT, MAX_PUBLICATION_SURFACE_HOOK_TIMEOUT_MS, type PublicationAttempt, type PublicationAttemptState, PublicationNotFoundError, type PublicationOperation, PublicationPointerMoveError, type PublicationReconciler, PublicationReconciliationError, type PublicationReconciliationInput, type PublicationSurfaceCommitStatus, type PublicationSurfacePhase, type PublicationSurfaceReceipt, PublicationSurfaceRequirementError, type PublicationSurfaceStatus, type PublishOneInput, type PublishOneReceipt, publishOne, type RetryPublicationSurfacesInput, type RetryPublicationSurfacesReceipt, type RollbackPublicationInput, type RollbackPublicationReceipt, retryPublicationSurfaces, rollbackPublication, type SkippedArchiveItem, } from './publication.js';
15
15
  export { evaluateArticleBody, type PublishGuardOptions, type PublishGuardOutcome, publishGuardResponseOrNull, } from './publish-guard.js';
16
16
  export { type ArticleInput, assertContentBodyValidForPublish, type BaseContentInput, type ContentItemRecord, type CreateContentInput, claimScheduledForPublish, countWords, createContent, createRevision, duplicateContentItem, ensureUniqueSlug, estimateReadTime, evaluateContentBodyForPublish, getContentItem, getContentRelations, getContentSnapshot, type NewsletterInput, type PodcastInput, PublishContentValidationError, publishContent, scheduleContent, setContentRelations, setContentTags, type UpdateContentInput, unpublishContent, updateContentItem, type VideoInput, } from './publisher.js';
17
+ export { type ClearManualReadStateOptions, type ContentStateKey, clearManualReadState, clearReaderHistory, DEFAULT_READER_STATE_BATCH_SIZE, deleteReaderState, exportReaderStatePage, getReaderState, getReaderStateBatch, listReaderState, MAX_READER_STATE_BATCH_SIZE, READER_AUTOMATIC_COMPLETION_BPS, type ReaderBehavioralConsent, type ReaderPreferences, type ReaderPreferenceValue, ReaderStateConflictError, ReaderStateDurableStateError, type ReaderStateExportPage, ReaderStateInputError, type ReaderStateListOptions, type ReaderStateMutationResult, type ReaderStatePage, type ReaderStateRecord, type ReaderStateScope, type RecordReaderOpenOptions, type RecordReaderProgressOptions, recordReaderOpen, recordReaderProgress, recordReaderUnlock, type SetManualReadStateOptions, type SetReaderPreferencesOptions, type SetSavedStateOptions, setManualReadState, setReaderPreferences, setSavedState, } from './reader-state.js';
17
18
  export { type ContentRevisionPayload, createRevisionWithDelta, getRevision, listRevisions, type RevisionSummary, restoreRevision, } from './revisions.js';
18
19
  export { decodeHeadingEntities, type SanitizeOptions, sanitize, sanitizeBody, stripOverEscapes, } from './sanitize.js';
19
20
  export { type SeedMembershipInput, seedMembership } from './seed-membership.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEnE,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,kBAAkB,EAClB,eAAe,EACf,KAAK,0BAA0B,EAC/B,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,eAAe,EACf,KAAK,oBAAoB,EACzB,eAAe,GACf,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,YAAY,EACZ,aAAa,EACb,iBAAiB,GACjB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACN,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,YAAY,EACZ,SAAS,EACT,KAAK,kBAAkB,EACvB,eAAe,GACf,MAAM,eAAe,CAAA;AAEtB,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,eAAe,GACf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,mBAAmB,EAAE,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAE5E,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAExE,OAAO,EACN,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,iBAAiB,EACjB,KAAK,eAAe,EACpB,UAAU,GACV,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EACN,cAAc,EACd,KAAK,gBAAgB,EACrB,UAAU,EACV,aAAa,EACb,gBAAgB,GAChB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EACN,KAAK,iBAAiB,EACtB,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,YAAY,EACZ,eAAe,EACf,KAAK,YAAY,EACjB,iBAAiB,GACjB,MAAM,cAAc,CAAA;AAErB,OAAO,EACN,WAAW,EACX,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,YAAY,EACZ,OAAO,EACP,KAAK,uBAAuB,EAC5B,kBAAkB,GAClB,MAAM,cAAc,CAAA;AAErB,OAAO,EACN,mBAAmB,EACnB,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,UAAU,GACV,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EACN,eAAe,EACf,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,eAAe,GACpB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACN,8BAA8B,EAC9B,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,yCAAyC,EACzC,2CAA2C,EAC3C,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,qCAAqC,EAC1C,8BAA8B,EAC9B,qCAAqC,EACrC,uCAAuC,EACvC,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,wBAAwB,EACxB,KAAK,oBAAoB,EACzB,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,8BAA8B,EAC9B,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACnC,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,kCAAkC,EAClC,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,UAAU,EACV,KAAK,6BAA6B,EAClC,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,wBAAwB,EACxB,mBAAmB,EACnB,KAAK,kBAAkB,GACvB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACN,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,0BAA0B,GAC1B,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EACN,KAAK,YAAY,EACjB,gCAAgC,EAChC,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,wBAAwB,EACxB,UAAU,EACV,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,6BAA6B,EAC7B,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,6BAA6B,EAC7B,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,KAAK,kBAAkB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,UAAU,GACf,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACN,KAAK,sBAAsB,EAC3B,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,KAAK,eAAe,EACpB,eAAe,GACf,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACN,qBAAqB,EACrB,KAAK,eAAe,EACpB,QAAQ,EACR,YAAY,EACZ,gBAAgB,GAChB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,KAAK,mBAAmB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE/E,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,UAAU,GACV,MAAM,UAAU,CAAA;AAEjB,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,OAAO,EACP,kBAAkB,GAClB,MAAM,WAAW,CAAA;AAElB,OAAO,EACN,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EACN,aAAa,EACb,YAAY,EACZ,cAAc,EACd,iBAAiB,GACjB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACN,SAAS,EACT,QAAQ,EACR,SAAS,EACT,UAAU,EACV,KAAK,UAAU,GACf,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,KAAK,cAAc,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExE,OAAO,EACN,KAAK,gBAAgB,EACrB,WAAW,EACX,sBAAsB,EACtB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,UAAU,GACV,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACN,2BAA2B,EAC3B,eAAe,EACf,oBAAoB,GACpB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EACN,KAAK,yBAAyB,EAC9B,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,GAClB,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,8 @@ export { ContentArchiveImportLimitError, DEFAULT_PENDING_PUBLICATION_ATTEMPT_LIM
32
32
  export { evaluateArticleBody, publishGuardResponseOrNull, } from './publish-guard.js';
33
33
  // The publishing engine — content data-access core.
34
34
  export { assertContentBodyValidForPublish, claimScheduledForPublish, countWords, createContent, createRevision, duplicateContentItem, ensureUniqueSlug, estimateReadTime, evaluateContentBodyForPublish, getContentItem, getContentRelations, getContentSnapshot, PublishContentValidationError, publishContent, scheduleContent, setContentRelations, setContentTags, unpublishContent, updateContentItem, } from './publisher.js';
35
+ // Verified-user/site reader product state. Analytics remains observation-only.
36
+ export { clearManualReadState, clearReaderHistory, DEFAULT_READER_STATE_BATCH_SIZE, deleteReaderState, exportReaderStatePage, getReaderState, getReaderStateBatch, listReaderState, MAX_READER_STATE_BATCH_SIZE, READER_AUTOMATIC_COMPLETION_BPS, ReaderStateConflictError, ReaderStateDurableStateError, ReaderStateInputError, recordReaderOpen, recordReaderProgress, recordReaderUnlock, setManualReadState, setReaderPreferences, setSavedState, } from './reader-state.js';
35
37
  // Revision engine — snapshot + word-delta history + restore.
36
38
  export { createRevisionWithDelta, getRevision, listRevisions, restoreRevision, } from './revisions.js';
37
39
  // Content-integrity sanitize passes (reuse the validator repair fns).
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ import type { ContentType, ReaderManualReadState } from '../schema/types.js';
2
+ import type { D1Database } from './d1.js';
3
+ export declare const READER_AUTOMATIC_COMPLETION_BPS = 9000;
4
+ export declare const DEFAULT_READER_STATE_BATCH_SIZE = 50;
5
+ export declare const MAX_READER_STATE_BATCH_SIZE = 100;
6
+ /**
7
+ * Verified request scope supplied by the consuming site after issuer and site
8
+ * token validation. The package validates the canonical raw identifier shape;
9
+ * callers must never construct this from analytics, email, local-user, URL, or
10
+ * request-body identifiers.
11
+ */
12
+ export interface ReaderStateScope {
13
+ identityUserId: string;
14
+ siteId: string;
15
+ }
16
+ export interface ContentStateKey {
17
+ contentType: ContentType;
18
+ contentId: string;
19
+ }
20
+ export type ReaderBehavioralConsent = 'granted' | 'denied';
21
+ export type ReaderPreferenceValue = string | number | boolean | null;
22
+ export type ReaderPreferences = Record<string, ReaderPreferenceValue>;
23
+ export interface ReaderStateRecord {
24
+ identityUserId: string;
25
+ siteId: string;
26
+ contentType: ContentType;
27
+ contentId: string;
28
+ firstOpenedAt: number | null;
29
+ lastOpenedAt: number | null;
30
+ maxProgressBasisPoints: number;
31
+ mediaPositionMs: number | null;
32
+ mediaDurationMs: number | null;
33
+ progressObservedAt: number | null;
34
+ automaticCompletedAt: number | null;
35
+ manualReadState: ReaderManualReadState | null;
36
+ manualStateAt: number | null;
37
+ saved: boolean;
38
+ savedAt: number | null;
39
+ preferences: ReaderPreferences;
40
+ preferencesAt: number | null;
41
+ version: number;
42
+ effectiveRead: boolean;
43
+ createdAt: number;
44
+ updatedAt: number;
45
+ }
46
+ export interface ReaderStateMutationResult {
47
+ applied: boolean;
48
+ reason: 'applied' | 'stale';
49
+ state: ReaderStateRecord;
50
+ }
51
+ export type ReaderStateBehaviorResult = ReaderStateMutationResult | {
52
+ applied: false;
53
+ reason: 'consent_denied';
54
+ state: ReaderStateRecord | null;
55
+ };
56
+ export interface ReaderStateListOptions {
57
+ limit?: number;
58
+ cursor?: string | null;
59
+ }
60
+ export interface ReaderStatePage {
61
+ items: ReaderStateRecord[];
62
+ nextCursor: string | null;
63
+ }
64
+ export interface ReaderStateExportPage extends ReaderStatePage {
65
+ scope: ReaderStateScope;
66
+ exportedAt: number;
67
+ }
68
+ interface BehavioralWriteOptions {
69
+ behavioralConsent: ReaderBehavioralConsent;
70
+ occurredAt?: number;
71
+ expectedVersion?: number;
72
+ }
73
+ export interface RecordReaderOpenOptions extends BehavioralWriteOptions {
74
+ }
75
+ export interface RecordReaderProgressOptions extends BehavioralWriteOptions {
76
+ progressBasisPoints: number;
77
+ mediaPositionMs?: number;
78
+ mediaDurationMs?: number;
79
+ }
80
+ interface ExplicitMutationOptions {
81
+ occurredAt?: number;
82
+ mutationId: string;
83
+ expectedVersion?: number;
84
+ }
85
+ export interface SetManualReadStateOptions extends ExplicitMutationOptions {
86
+ state: ReaderManualReadState;
87
+ }
88
+ export interface ClearManualReadStateOptions extends ExplicitMutationOptions {
89
+ }
90
+ export interface SetSavedStateOptions extends ExplicitMutationOptions {
91
+ saved: boolean;
92
+ }
93
+ export interface SetReaderPreferencesOptions extends ExplicitMutationOptions {
94
+ preferences: ReaderPreferences;
95
+ }
96
+ export declare class ReaderStateInputError extends Error {
97
+ constructor(message: string);
98
+ }
99
+ export declare class ReaderStateConflictError extends Error {
100
+ readonly expectedVersion: number;
101
+ readonly actualVersion: number | null;
102
+ constructor(expectedVersion: number, actualVersion: number | null);
103
+ }
104
+ export declare class ReaderStateDurableStateError extends Error {
105
+ constructor(message: string);
106
+ }
107
+ export declare function getReaderState(db: D1Database, scope: ReaderStateScope, key: ContentStateKey): Promise<ReaderStateRecord | null>;
108
+ /** Unlock is intentionally a read-only observation: it never creates or completes state. */
109
+ export declare function recordReaderUnlock(db: D1Database, scope: ReaderStateScope, key: ContentStateKey): Promise<ReaderStateRecord | null>;
110
+ export declare function recordReaderOpen(db: D1Database, scope: ReaderStateScope, key: ContentStateKey, options: RecordReaderOpenOptions): Promise<ReaderStateBehaviorResult>;
111
+ export declare function recordReaderProgress(db: D1Database, scope: ReaderStateScope, key: ContentStateKey, options: RecordReaderProgressOptions): Promise<ReaderStateBehaviorResult>;
112
+ export declare function setManualReadState(db: D1Database, scope: ReaderStateScope, key: ContentStateKey, options: SetManualReadStateOptions): Promise<ReaderStateMutationResult>;
113
+ export declare function clearManualReadState(db: D1Database, scope: ReaderStateScope, key: ContentStateKey, options: ClearManualReadStateOptions): Promise<ReaderStateMutationResult>;
114
+ export declare function setSavedState(db: D1Database, scope: ReaderStateScope, key: ContentStateKey, options: SetSavedStateOptions): Promise<ReaderStateMutationResult>;
115
+ export declare function setReaderPreferences(db: D1Database, scope: ReaderStateScope, key: ContentStateKey, options: SetReaderPreferencesOptions): Promise<ReaderStateMutationResult>;
116
+ export declare function getReaderStateBatch(db: D1Database, scope: ReaderStateScope, keys: readonly ContentStateKey[]): Promise<ReaderStateRecord[]>;
117
+ export declare function listReaderState(db: D1Database, scope: ReaderStateScope, options?: ReaderStateListOptions): Promise<ReaderStatePage>;
118
+ export declare function exportReaderStatePage(db: D1Database, scope: ReaderStateScope, options?: ReaderStateListOptions): Promise<ReaderStateExportPage>;
119
+ /**
120
+ * Consent-withdrawal/privacy clear: remove behavioral history while retaining
121
+ * explicit read/unread, save, and stated preference choices.
122
+ */
123
+ export declare function clearReaderHistory(db: D1Database, scope: ReaderStateScope): Promise<number>;
124
+ /** Delete every row for exactly one verified user/site scope. */
125
+ export declare function deleteReaderState(db: D1Database, scope: ReaderStateScope): Promise<number>;
126
+ export {};
127
+ //# sourceMappingURL=reader-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader-state.d.ts","sourceRoot":"","sources":["../../src/engine/reader-state.ts"],"names":[],"mappings":"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"}