@cosmicdrift/kumiko-bundled-features 0.394.0 → 0.396.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 (78) hide show
  1. package/dist/inbound-provider-imap/feature.js +2 -91
  2. package/dist/inbound-provider-imap/watch-mailbox.d.ts +5 -0
  3. package/dist/inbound-provider-imap/watch-mailbox.js +92 -0
  4. package/dist/managed-pages/constants.d.ts +1 -0
  5. package/dist/managed-pages/constants.js +1 -0
  6. package/dist/managed-pages/feature.js +5 -3
  7. package/dist/managed-pages/handlers/by-slug.query.d.ts +1 -0
  8. package/dist/managed-pages/handlers/by-slug.query.js +2 -0
  9. package/dist/managed-pages/handlers/page-body-guard.d.ts +2 -0
  10. package/dist/managed-pages/handlers/page-body-guard.js +46 -0
  11. package/dist/managed-pages/handlers/page-body-issues.d.ts +10 -0
  12. package/dist/managed-pages/handlers/page-body-issues.js +21 -0
  13. package/dist/managed-pages/handlers/page-crud.js +5 -4
  14. package/dist/managed-pages/handlers/set.write.d.ts +4 -0
  15. package/dist/managed-pages/handlers/set.write.js +16 -4
  16. package/dist/managed-pages/render-page-body.d.ts +10 -0
  17. package/dist/managed-pages/render-page-body.js +19 -0
  18. package/dist/managed-pages/screens/page-screens.js +6 -2
  19. package/dist/managed-pages/seeding.d.ts +2 -0
  20. package/dist/managed-pages/seeding.js +12 -2
  21. package/dist/managed-pages/table.d.ts +46 -0
  22. package/dist/managed-pages/table.js +5 -3
  23. package/dist/managed-pages/web/client-plugin.js +6 -4
  24. package/dist/managed-pages/web/constants.d.ts +5 -0
  25. package/dist/managed-pages/web/constants.js +9 -0
  26. package/dist/managed-pages/web/i18n.js +12 -0
  27. package/dist/managed-pages/web/lossy-markdown.d.ts +3 -0
  28. package/dist/managed-pages/web/lossy-markdown.js +59 -0
  29. package/dist/managed-pages/web/markdown-to-document.d.ts +1 -0
  30. package/dist/managed-pages/web/markdown-to-document.js +26 -0
  31. package/dist/managed-pages/web/page-body-section.d.ts +3 -0
  32. package/dist/managed-pages/web/page-body-section.js +41 -0
  33. package/dist/template-resolver/document-sanitizer.d.ts +6 -2
  34. package/dist/template-resolver/document-sanitizer.js +5 -4
  35. package/dist/template-resolver/feature.js +12 -1
  36. package/dist/template-resolver/handlers/collection-set.write.d.ts +1 -6
  37. package/dist/template-resolver/handlers/collection-set.write.js +21 -6
  38. package/dist/template-resolver/handlers/collection-shared.d.ts +2 -0
  39. package/dist/template-resolver/handlers/collection-shared.js +5 -0
  40. package/dist/template-resolver/handlers/set.write.js +1 -0
  41. package/dist/template-resolver/handlers/shared.js +3 -3
  42. package/dist/template-resolver/web/client-plugin.d.ts +0 -15
  43. package/dist/template-resolver/web/client-plugin.js +8 -363
  44. package/dist/template-resolver/web/collection-entry-create-form.d.ts +11 -0
  45. package/dist/template-resolver/web/collection-entry-create-form.js +31 -0
  46. package/dist/template-resolver/web/collection-lookup.d.ts +4 -0
  47. package/dist/template-resolver/web/collection-lookup.js +24 -0
  48. package/dist/template-resolver/web/constants.d.ts +2 -0
  49. package/dist/template-resolver/web/constants.js +2 -0
  50. package/dist/template-resolver/web/content-field.d.ts +9 -0
  51. package/dist/template-resolver/web/content-field.js +14 -0
  52. package/dist/template-resolver/web/content-tree-provider.d.ts +14 -0
  53. package/dist/template-resolver/web/content-tree-provider.js +197 -0
  54. package/dist/template-resolver/web/document-reference-name.d.ts +1 -0
  55. package/dist/template-resolver/web/document-reference-name.js +9 -0
  56. package/dist/template-resolver/web/document-schema.d.ts +2 -1
  57. package/dist/template-resolver/web/document-schema.js +2 -8
  58. package/dist/template-resolver/web/i18n.js +6 -0
  59. package/dist/template-resolver/web/legacy-variable-text.d.ts +1 -0
  60. package/dist/template-resolver/web/legacy-variable-text.js +23 -0
  61. package/dist/template-resolver/web/tenant-override.d.ts +3 -0
  62. package/dist/template-resolver/web/tenant-override.js +4 -0
  63. package/dist/template-resolver/web/text-block-editor.d.ts +6 -0
  64. package/dist/template-resolver/web/text-block-editor.js +22 -0
  65. package/dist/template-resolver/web/use-collection-editor-context.d.ts +14 -0
  66. package/dist/template-resolver/web/use-collection-editor-context.js +21 -0
  67. package/dist/template-resolver/web/use-collection-entry-create.d.ts +18 -0
  68. package/dist/template-resolver/web/use-collection-entry-create.js +78 -0
  69. package/dist/template-resolver/web/use-content-write.d.ts +17 -0
  70. package/dist/template-resolver/web/use-content-write.js +54 -0
  71. package/dist/template-resolver/web/use-text-block-editor.d.ts +19 -0
  72. package/dist/template-resolver/web/use-text-block-editor.js +85 -0
  73. package/dist/tier-engine/feature.js +9 -1
  74. package/package.json +11 -11
  75. package/src/inbound-provider-imap/changes.json +6 -0
  76. package/src/managed-pages/changes.json +7 -0
  77. package/src/template-resolver/changes.json +8 -0
  78. package/src/tier-engine/changes.json +6 -0
@@ -232,6 +232,7 @@ export function createTierEngineFeature(opts = {}) {
232
232
  // reload result is applied only while its ticket is still the tenant's latest.
233
233
  let ticketCounter = 0;
234
234
  const latestTicket = new Map();
235
+ let isBuilt = false;
235
236
  const takeTicket = (tenantId) => {
236
237
  ticketCounter += 1;
237
238
  latestTicket.set(tenantId, ticketCounter);
@@ -261,7 +262,9 @@ export function createTierEngineFeature(opts = {}) {
261
262
  // bus and re-read the row.
262
263
  const applyAssignment = (tenantId, tier) => {
263
264
  takeTicket(tenantId);
264
- cache.set(tenantId, mergeAlwaysOn(alwaysOnHolder.set, featuresForTier(tierMap, tier)));
265
+ // Before build() the always-on set is empty; a cached entry would outlive into the next build.
266
+ if (isBuilt)
267
+ cache.set(tenantId, mergeAlwaysOn(alwaysOnHolder.set, featuresForTier(tierMap, tier)));
265
268
  publishAssignmentChange(tenantId);
266
269
  };
267
270
  onTierAssigned.fn = applyAssignment;
@@ -398,6 +401,11 @@ export function createTierEngineFeature(opts = {}) {
398
401
  computedAlwaysOn.add(feature.name);
399
402
  }
400
403
  alwaysOnHolder.set = computedAlwaysOn;
404
+ // One feature instance can serve several stacks in a process; rebuild state from this DB only.
405
+ // Safe vs. "never clear-then-refill": no request reaches this resolver before build() returns.
406
+ cache.clear();
407
+ latestTicket.clear();
408
+ isBuilt = true;
401
409
  const rows = await selectMany(systemDb, tierAssignmentTable);
402
410
  for (const row of rows) {
403
411
  cache.set(row.tenantId, mergeAlwaysOn(computedAlwaysOn, featuresForTier(tierMap, row.tier)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-bundled-features",
3
- "version": "0.394.0",
3
+ "version": "0.396.0",
4
4
  "description": "Built-in features — tenant, user, auth, delivery. The stuff you'd rewrite anyway, already typed.",
5
5
  "license": "MIT",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -566,9 +566,9 @@
566
566
  }
567
567
  },
568
568
  "dependencies": {
569
- "@cosmicdrift/kumiko-framework": "0.394.0",
570
- "@cosmicdrift/kumiko-renderer": "0.394.0",
571
- "@cosmicdrift/kumiko-types": "0.394.0",
569
+ "@cosmicdrift/kumiko-framework": "0.396.0",
570
+ "@cosmicdrift/kumiko-renderer": "0.396.0",
571
+ "@cosmicdrift/kumiko-types": "0.396.0",
572
572
  "@mollie/api-client": "^4.5.0",
573
573
  "@node-rs/argon2": "^2.0.2",
574
574
  "@tiptap/core": "^3.31.3",
@@ -1158,17 +1158,17 @@
1158
1158
  ],
1159
1159
  "devDependencies": {
1160
1160
  "@testing-library/user-event": "^14.6.1",
1161
- "@cosmicdrift/kumiko-locale-de": "0.394.0",
1162
- "@cosmicdrift/kumiko-locale-es": "0.394.0",
1163
- "@cosmicdrift/kumiko-locale-fr": "0.394.0",
1164
- "@cosmicdrift/kumiko-locale-it": "0.394.0",
1165
- "@cosmicdrift/kumiko-renderer-mail-html": "0.394.0",
1161
+ "@cosmicdrift/kumiko-locale-de": "0.396.0",
1162
+ "@cosmicdrift/kumiko-locale-es": "0.396.0",
1163
+ "@cosmicdrift/kumiko-locale-fr": "0.396.0",
1164
+ "@cosmicdrift/kumiko-locale-it": "0.396.0",
1165
+ "@cosmicdrift/kumiko-renderer-mail-html": "0.396.0",
1166
1166
  "jsqr": "^1.4.0",
1167
1167
  "unpdf": "^1.8.1",
1168
- "@cosmicdrift/kumiko-testing": "0.394.0"
1168
+ "@cosmicdrift/kumiko-testing": "0.396.0"
1169
1169
  },
1170
1170
  "peerDependencies": {
1171
- "@cosmicdrift/kumiko-testing": "0.394.0"
1171
+ "@cosmicdrift/kumiko-testing": "0.396.0"
1172
1172
  },
1173
1173
  "peerDependenciesMeta": {
1174
1174
  "@cosmicdrift/kumiko-testing": {
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.395.0",
4
+ "type": "fix",
5
+ "title": "A mail the IMAP watch quarantines keeps its sender and subject",
6
+ "detail": "The live watch fetched new mails without the IMAP envelope, so an unparseable mail it quarantined showed no sender and no subject in the quarantine list. The watch now fetches the envelope like the poll does."
7
+ },
2
8
  {
3
9
  "version": "0.394.0",
4
10
  "type": "improvement",
@@ -1,4 +1,11 @@
1
1
  [
2
+ {
3
+ "version": "0.395.0",
4
+ "type": "breaking",
5
+ "title": "A managed page body is Markdown or an editor document, edited in the document editor",
6
+ "detail": "The page entity has a new field bodyFormat (\"markdown\" or \"document\", default markdown). Pages and events from before the field read as markdown and render unchanged. A document body is HTML from the template-resolver document editor; page create, update and managed-pages:write:set check it with sanitizeDocumentHtml and store the rebuilt HTML and answer a rejected body with field errors on body (i18n key managed-pages.errors.document.rejected, new in all locale packages). The public render sanitizes a document body again and serves an empty body, with a logged warning, when a stored one fails. managed-pages:write:set takes an optional bodyFormat; omitting it sets markdown, it does not preserve the stored format. The page-edit screen no longer has a body textarea: its body section is the extension section managed-pages:page-body (PAGE_BODY_EXTENSION_NAME), which opens a Markdown body converted to HTML, shows a warning for what the conversion drops (images, block quotes, code, headings below level 3, relative links) and writes body and bodyFormat \"document\" only after the first edit. The ETag of the public page includes bodyFormat. seedPage takes an optional bodyFormat and throws on a rejected document body.",
7
+ "migration": "Run `kumiko-schema generate` and apply the migration; read_pages gets a bodyFormat column with default 'markdown', no rebuild is needed. Mount `managedPagesClient()` from `@cosmicdrift/kumiko-bundled-features/managed-pages/web` in createKumikoApp({ clientFeatures }); without it the body section of page-edit shows the missing-component placeholder. Apps that replaced page-edit with their own screen keep the textarea and send no bodyFormat, so their pages stay markdown."
8
+ },
2
9
  {
3
10
  "version": "0.389.0",
4
11
  "type": "improvement",
@@ -1,4 +1,12 @@
1
1
  [
2
+ {
3
+ "version": "0.395.0",
4
+ "type": "breaking",
5
+ "title": "Content collections edit in plain or document format; rich and markdown are gone",
6
+ "detail": "ContentEditorFormat is \"plain\" | \"document\". RichContentEditor and the old tiptap editor are removed from @cosmicdrift/kumiko-renderer/web; the document editor is DocumentContentEditor from @cosmicdrift/kumiko-bundled-features/template-resolver/web. A collection's storage format comes from its declaration on the server (plain stores plain, document stores html sanitized with sanitizeDocumentHtml for every collection kind) and the collection write no longer takes contentFormat. Saved content with {{name}} as text opens with variable nodes. Every collection gets a create form behind a \"+\" in its nav (unless it declares its own createAction); the collection write takes createOnly and answers an existing slug with the field error slug_exists. The text block editor and the secrets edit screen use FormScreenLayout, which takes an optional unsavedCount. useDispatchTarget is exported from @cosmicdrift/kumiko-renderer/web.",
7
+ "migration": "Run bun kumiko-upgrade --apply. It rewrites contentFormat \"rich\" and \"markdown\" in collection declarations to \"document\". Replace imports of RichContentEditor with DocumentContentEditor from @cosmicdrift/kumiko-bundled-features/template-resolver/web, and drop contentFormat from collection write payloads.",
8
+ "codemod": "scripts/codemod/content-collection-format.ts"
9
+ },
2
10
  {
3
11
  "version": "0.394.0",
4
12
  "type": "fix",
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.395.0",
4
+ "type": "fix",
5
+ "title": "The tier resolver no longer keeps tier writes made before its build",
6
+ "detail": "A tier write that ran before build() cached a feature set without the always-on features, and a later build() left that entry in place, so the tenant got feature_disabled instead of the default fallback. build() now starts from an empty cache and writes before it are not cached."
7
+ },
2
8
  {
3
9
  "version": "0.392.0",
4
10
  "type": "fix",