@decocms/start 0.19.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 (185) hide show
  1. package/.cursor/skills/deco-api-call-dedup/SKILL.md +443 -0
  2. package/.cursor/skills/deco-apps-architecture/SKILL.md +255 -0
  3. package/.cursor/skills/deco-apps-architecture/app-pattern.md +288 -0
  4. package/.cursor/skills/deco-apps-architecture/commerce-types.md +239 -0
  5. package/.cursor/skills/deco-apps-architecture/new-app-guide.md +268 -0
  6. package/.cursor/skills/deco-apps-architecture/scripts-codegen.md +148 -0
  7. package/.cursor/skills/deco-apps-architecture/shared-utils.md +181 -0
  8. package/.cursor/skills/deco-apps-architecture/vtex-deep-structure.md +253 -0
  9. package/.cursor/skills/deco-apps-architecture/website-app.md +169 -0
  10. package/.cursor/skills/deco-apps-vtex-porting/SKILL.md +189 -0
  11. package/.cursor/skills/deco-apps-vtex-porting/adaptation-patterns.md +335 -0
  12. package/.cursor/skills/deco-apps-vtex-porting/commerce-porting.md +155 -0
  13. package/.cursor/skills/deco-apps-vtex-porting/cookie-auth-patterns.md +148 -0
  14. package/.cursor/skills/deco-apps-vtex-porting/structure-map.md +234 -0
  15. package/.cursor/skills/deco-apps-vtex-porting/transform-mapping.md +99 -0
  16. package/.cursor/skills/deco-apps-vtex-porting/website-porting.md +194 -0
  17. package/.cursor/skills/deco-apps-vtex-review/SKILL.md +234 -0
  18. package/.cursor/skills/deco-async-rendering-architecture/SKILL.md +270 -0
  19. package/.cursor/skills/deco-async-rendering-site-guide/SKILL.md +417 -0
  20. package/.cursor/skills/deco-cms-layout-caching/SKILL.md +293 -0
  21. package/.cursor/skills/deco-cms-route-config/SKILL.md +388 -0
  22. package/.cursor/skills/deco-core-architecture/SKILL.md +185 -0
  23. package/.cursor/skills/deco-core-architecture/blocks.md +196 -0
  24. package/.cursor/skills/deco-core-architecture/deco-vs-deco-start.md +191 -0
  25. package/.cursor/skills/deco-core-architecture/engine.md +220 -0
  26. package/.cursor/skills/deco-core-architecture/hooks-components.md +157 -0
  27. package/.cursor/skills/deco-core-architecture/plugins-clients.md +136 -0
  28. package/.cursor/skills/deco-core-architecture/runtime.md +116 -0
  29. package/.cursor/skills/deco-core-architecture/site-usage.md +165 -0
  30. package/.cursor/skills/deco-e2e-testing/SKILL.md +372 -0
  31. package/.cursor/skills/deco-e2e-testing/discovery.md +337 -0
  32. package/.cursor/skills/deco-e2e-testing/scripts/scaffold.sh +81 -0
  33. package/.cursor/skills/deco-e2e-testing/selectors.md +175 -0
  34. package/.cursor/skills/deco-e2e-testing/templates/package.json +18 -0
  35. package/.cursor/skills/deco-e2e-testing/templates/playwright.config.ts +65 -0
  36. package/.cursor/skills/deco-e2e-testing/templates/scripts/baseline.ts +279 -0
  37. package/.cursor/skills/deco-e2e-testing/templates/scripts/run-e2e.ts +194 -0
  38. package/.cursor/skills/deco-e2e-testing/templates/specs/ecommerce-flow.spec.ts +612 -0
  39. package/.cursor/skills/deco-e2e-testing/templates/tsconfig.json +12 -0
  40. package/.cursor/skills/deco-e2e-testing/templates/utils/metrics-collector.ts +918 -0
  41. package/.cursor/skills/deco-e2e-testing/troubleshooting.md +602 -0
  42. package/.cursor/skills/deco-edge-caching/SKILL.md +316 -0
  43. package/.cursor/skills/deco-full-analysis/SKILL.md +898 -0
  44. package/.cursor/skills/deco-full-analysis/checklists/asset-optimization.md +251 -0
  45. package/.cursor/skills/deco-full-analysis/checklists/bug-fix.md +189 -0
  46. package/.cursor/skills/deco-full-analysis/checklists/cache-strategy.md +144 -0
  47. package/.cursor/skills/deco-full-analysis/checklists/dependency-update.md +150 -0
  48. package/.cursor/skills/deco-full-analysis/checklists/hydration-fix.md +191 -0
  49. package/.cursor/skills/deco-full-analysis/checklists/image-optimization.md +180 -0
  50. package/.cursor/skills/deco-full-analysis/checklists/loader-optimization.md +165 -0
  51. package/.cursor/skills/deco-full-analysis/checklists/seo-fix.md +183 -0
  52. package/.cursor/skills/deco-full-analysis/checklists/site-cleanup.md +281 -0
  53. package/.cursor/skills/deco-full-analysis/discovery.md +548 -0
  54. package/.cursor/skills/deco-incident-debugging/SKILL.md +378 -0
  55. package/.cursor/skills/deco-incident-debugging/headless-mode.md +510 -0
  56. package/.cursor/skills/deco-incident-debugging/learnings-index.md +227 -0
  57. package/.cursor/skills/deco-incident-debugging/triage-workflow.md +312 -0
  58. package/.cursor/skills/deco-islands-migration/SKILL.md +251 -0
  59. package/.cursor/skills/deco-loader-n-plus-1-detector/SKILL.md +275 -0
  60. package/.cursor/skills/deco-performance-audit/SKILL.md +530 -0
  61. package/.cursor/skills/deco-performance-audit/tools-reference.md +428 -0
  62. package/.cursor/skills/deco-performance-audit/workflow.md +457 -0
  63. package/.cursor/skills/deco-server-functions-invoke/SKILL.md +92 -0
  64. package/.cursor/skills/deco-server-functions-invoke/architecture.md +166 -0
  65. package/.cursor/skills/deco-server-functions-invoke/generator.md +122 -0
  66. package/.cursor/skills/deco-server-functions-invoke/problem.md +98 -0
  67. package/.cursor/skills/deco-server-functions-invoke/troubleshooting.md +110 -0
  68. package/.cursor/skills/deco-site-deployment/SKILL.md +396 -0
  69. package/.cursor/skills/deco-site-memory-debugging/SKILL.md +121 -0
  70. package/.cursor/skills/deco-site-memory-debugging/cdp-connection.md +222 -0
  71. package/.cursor/skills/deco-site-memory-debugging/memory-analysis.md +362 -0
  72. package/.cursor/skills/deco-site-patterns/SKILL.md +124 -0
  73. package/.cursor/skills/deco-site-patterns/app-composition.md +337 -0
  74. package/.cursor/skills/deco-site-patterns/client-patterns.md +341 -0
  75. package/.cursor/skills/deco-site-patterns/cms-wiring.md +230 -0
  76. package/.cursor/skills/deco-site-patterns/section-patterns.md +340 -0
  77. package/.cursor/skills/deco-site-scaling-tuning/SKILL.md +240 -0
  78. package/.cursor/skills/deco-site-scaling-tuning/analysis-scripts.md +267 -0
  79. package/.cursor/skills/deco-start-architecture/SKILL.md +218 -0
  80. package/.cursor/skills/deco-start-architecture/admin-protocol.md +156 -0
  81. package/.cursor/skills/deco-start-architecture/cms-resolution.md +201 -0
  82. package/.cursor/skills/deco-start-architecture/code-quality.md +158 -0
  83. package/.cursor/skills/deco-start-architecture/gap-analysis.md +129 -0
  84. package/.cursor/skills/deco-start-architecture/sdk-utilities.md +197 -0
  85. package/.cursor/skills/deco-start-architecture/worker-entry-caching.md +154 -0
  86. package/.cursor/skills/deco-startup-analysis/SKILL.md +248 -0
  87. package/.cursor/skills/deco-storefront-test-checklist/SKILL.md +369 -0
  88. package/.cursor/skills/deco-tanstack-hydration-fixes/SKILL.md +468 -0
  89. package/.cursor/skills/deco-tanstack-navigation/SKILL.md +681 -0
  90. package/.cursor/skills/deco-tanstack-search/SKILL.md +411 -0
  91. package/.cursor/skills/deco-tanstack-storefront-patterns/SKILL.md +1013 -0
  92. package/.cursor/skills/deco-to-tanstack-migration/SKILL.md +518 -0
  93. package/.cursor/skills/deco-to-tanstack-migration/references/codemod-commands.md +174 -0
  94. package/.cursor/skills/deco-to-tanstack-migration/references/commerce/README.md +78 -0
  95. package/.cursor/skills/deco-to-tanstack-migration/references/deco-framework/README.md +128 -0
  96. package/.cursor/skills/deco-to-tanstack-migration/references/gotchas.md +719 -0
  97. package/.cursor/skills/deco-to-tanstack-migration/references/imports/README.md +70 -0
  98. package/.cursor/skills/deco-to-tanstack-migration/references/platform-hooks/README.md +154 -0
  99. package/.cursor/skills/deco-to-tanstack-migration/references/signals/README.md +220 -0
  100. package/.cursor/skills/deco-to-tanstack-migration/references/vite-config/README.md +78 -0
  101. package/.cursor/skills/deco-to-tanstack-migration/templates/package-json.md +55 -0
  102. package/.cursor/skills/deco-to-tanstack-migration/templates/root-route.md +110 -0
  103. package/.cursor/skills/deco-to-tanstack-migration/templates/router.md +96 -0
  104. package/.cursor/skills/deco-to-tanstack-migration/templates/setup-ts.md +167 -0
  105. package/.cursor/skills/deco-to-tanstack-migration/templates/vite-config.md +122 -0
  106. package/.cursor/skills/deco-to-tanstack-migration/templates/worker-entry.md +67 -0
  107. package/.cursor/skills/deco-typescript-fixes/SKILL.md +178 -0
  108. package/.cursor/skills/deco-typescript-fixes/common-fixes.md +330 -0
  109. package/.cursor/skills/deco-typescript-fixes/strategy.md +148 -0
  110. package/.cursor/skills/deco-variant-selection-perf/SKILL.md +272 -0
  111. package/.cursor/skills/deco-vtex-fetch-cache/SKILL.md +225 -0
  112. package/.cursor/skills/find-skills/SKILL.md +133 -0
  113. package/.cursor/skills/incident-report/SKILL.md +179 -0
  114. package/.cursor/skills/incident-report/references/5-whys.md +75 -0
  115. package/.cursor/skills/incident-report/templates/client-report.md +187 -0
  116. package/.cursor/skills/incident-report/templates/internal-report.md +206 -0
  117. package/.cursor/skills/template-skill/SKILL.md +38 -0
  118. package/.github/workflows/release.yml +32 -0
  119. package/.releaserc.json +25 -0
  120. package/CLAUDE.md +135 -0
  121. package/GAP_ANALYSIS.md +224 -0
  122. package/GAP_ANALYSIS_V2.md +1013 -0
  123. package/biome.json +39 -0
  124. package/knip.json +5 -0
  125. package/package.json +87 -0
  126. package/scripts/generate-blocks.ts +69 -0
  127. package/scripts/generate-invoke.ts +378 -0
  128. package/scripts/generate-schema.ts +657 -0
  129. package/src/admin/cors.ts +29 -0
  130. package/src/admin/decofile.ts +72 -0
  131. package/src/admin/index.ts +24 -0
  132. package/src/admin/invoke.ts +163 -0
  133. package/src/admin/liveControls.ts +29 -0
  134. package/src/admin/meta.ts +70 -0
  135. package/src/admin/render.ts +205 -0
  136. package/src/admin/schema.ts +686 -0
  137. package/src/admin/setup.ts +44 -0
  138. package/src/cms/index.ts +59 -0
  139. package/src/cms/loader.ts +180 -0
  140. package/src/cms/registry.ts +162 -0
  141. package/src/cms/resolve.ts +1005 -0
  142. package/src/cms/sectionLoaders.ts +294 -0
  143. package/src/hooks/DecoPageRenderer.tsx +444 -0
  144. package/src/hooks/LazySection.tsx +109 -0
  145. package/src/hooks/LiveControls.tsx +108 -0
  146. package/src/hooks/SectionErrorFallback.tsx +85 -0
  147. package/src/hooks/index.ts +8 -0
  148. package/src/index.ts +5 -0
  149. package/src/matchers/builtins.ts +184 -0
  150. package/src/matchers/posthog.ts +154 -0
  151. package/src/middleware/decoState.ts +55 -0
  152. package/src/middleware/healthMetrics.ts +131 -0
  153. package/src/middleware/index.ts +80 -0
  154. package/src/middleware/liveness.ts +21 -0
  155. package/src/middleware/observability.ts +205 -0
  156. package/src/routes/adminRoutes.ts +83 -0
  157. package/src/routes/cmsRoute.ts +302 -0
  158. package/src/routes/components.tsx +34 -0
  159. package/src/routes/index.ts +15 -0
  160. package/src/sdk/analytics.ts +72 -0
  161. package/src/sdk/cacheHeaders.ts +268 -0
  162. package/src/sdk/cachedLoader.ts +206 -0
  163. package/src/sdk/clx.ts +3 -0
  164. package/src/sdk/cookie.ts +39 -0
  165. package/src/sdk/createInvoke.ts +57 -0
  166. package/src/sdk/csp.ts +59 -0
  167. package/src/sdk/env.ts +27 -0
  168. package/src/sdk/index.ts +63 -0
  169. package/src/sdk/instrumentedFetch.ts +137 -0
  170. package/src/sdk/invoke.ts +133 -0
  171. package/src/sdk/mergeCacheControl.ts +150 -0
  172. package/src/sdk/redirects.ts +217 -0
  173. package/src/sdk/requestContext.ts +184 -0
  174. package/src/sdk/serverTimings.ts +68 -0
  175. package/src/sdk/signal.ts +41 -0
  176. package/src/sdk/sitemap.ts +143 -0
  177. package/src/sdk/urlUtils.ts +117 -0
  178. package/src/sdk/useDevice.ts +82 -0
  179. package/src/sdk/useId.ts +7 -0
  180. package/src/sdk/useScript.ts +101 -0
  181. package/src/sdk/workerEntry.ts +703 -0
  182. package/src/sdk/wrapCaughtErrors.ts +107 -0
  183. package/src/types/index.ts +39 -0
  184. package/src/types/widgets.ts +13 -0
  185. package/tsconfig.json +13 -0
@@ -0,0 +1,185 @@
1
+ ---
2
+ name: deco-core-architecture
3
+ description: Architecture reference for deco-cx/deco — the core Deco framework for Fresh/Deno. Covers the resolution engine (Resolvable → Resolver pipeline), block system (sections, loaders, actions, flags, matchers, handlers, apps, workflows), runtime request flow (Hono + Fresh/HTMX), DecofileProvider (state management), manifest generation, plugin system, hooks (useSection, useScript, useDevice), client-side invoke proxy, and the relationship between deco-cx/deco (Fresh/Deno) and @decocms/start (TanStack/Node). Use when exploring the deco repo, understanding how the framework works, building new block types, debugging resolution issues, or porting deco internals to TanStack Start.
4
+ globs:
5
+ - "**/deco.ts"
6
+ - "**/manifest.gen.ts"
7
+ - "**/mod.ts"
8
+ - "**/runtime.ts"
9
+ - "**/fresh.config.ts"
10
+ ---
11
+
12
+ ## Sub-documents
13
+
14
+ | Document | Topic |
15
+ |----------|-------|
16
+ | [engine.md](./engine.md) | Resolution engine — Resolvable, Resolver, DecofileProvider, resolve pipeline |
17
+ | [blocks.md](./blocks.md) | Block system — all block types, adapt/decorate, manifest registration |
18
+ | [runtime.md](./runtime.md) | Runtime request flow — Hono, middleware chain, routes, rendering |
19
+ | [hooks-components.md](./hooks-components.md) | Hooks, components, and client-side code |
20
+ | [plugins-clients.md](./plugins-clients.md) | Fresh plugins, client-side invoke proxy, formdata utils |
21
+ | [site-usage.md](./site-usage.md) | How a Deco site uses the framework — osklenbr as reference |
22
+ | [deco-vs-deco-start.md](./deco-vs-deco-start.md) | Mapping deco-cx/deco (Fresh) → @decocms/start (TanStack) |
23
+
24
+ # deco-cx/deco Core Architecture
25
+
26
+ Reference for the `deco-cx/deco` repository — the core Deco framework powering Fresh/Deno storefronts.
27
+
28
+ ## Repository Overview
29
+
30
+ ```
31
+ deco/
32
+ ├── mod.ts # Main entry — re-exports engine, runtime, blocks, context
33
+ ├── mod.web.ts # Web/client entry — invoke proxy, stream reader
34
+ ├── deco.ts # DecoContext, RequestContext, AsyncLocalStorage bindings
35
+ ├── live.ts # Re-export of deco.ts (legacy alias)
36
+ ├── types.ts # DecoManifest, DecoState, block type constants
37
+ ├── deps.ts # External deps (OpenTelemetry, std, durable, inspect)
38
+ ├── deno.json # v1.177.5 — imports, exports, tasks
39
+
40
+ ├── engine/ # Resolution engine (45 files)
41
+ │ ├── core/ # Resolver, Resolvable, resolve pipeline
42
+ │ ├── manifest/ # Manifest builder, generation, defaults
43
+ │ ├── decofile/ # State providers (filesystem, JSON, realtime)
44
+ │ ├── schema/ # JSON Schema generation and introspection
45
+ │ └── importmap/ # Import map builder for blocks
46
+
47
+ ├── blocks/ # Block definitions (15 files)
48
+ │ ├── section.ts # UI components with optional loader/action
49
+ │ ├── loader.ts # Data fetching blocks (cached, single-flight)
50
+ │ ├── action.ts # Mutation blocks
51
+ │ ├── handler.ts # HTTP request handlers
52
+ │ ├── flag.ts # Feature flags
53
+ │ ├── matcher.ts # Audience targeting predicates
54
+ │ ├── page.tsx # Page-level sections
55
+ │ ├── app.ts # App containers with manifest + state
56
+ │ ├── workflow.ts # Durable workflows
57
+ │ └── function.ts # Legacy loader format
58
+
59
+ ├── runtime/ # Request handling (51 files)
60
+ │ ├── mod.ts # Deco class — main runtime entry
61
+ │ ├── handler.tsx # Hono app setup, route registration
62
+ │ ├── middleware.ts # Middleware chain (liveness, state, o11y, response)
63
+ │ ├── routes/ # Built-in routes (/live/invoke, /deco/render, etc.)
64
+ │ ├── features/ # Invoke, render, meta, preview, styles
65
+ │ ├── fresh/ # Fresh framework plugin + Bindings
66
+ │ ├── htmx/ # HTMX framework (alternative renderer)
67
+ │ ├── fetch/ # Instrumented fetch (logging, caching)
68
+ │ └── caches/ # LRU, Redis, tiered, filesystem caches
69
+
70
+ ├── hooks/ # Server-side hooks (6 files)
71
+ ├── components/ # Framework components (5 files)
72
+ ├── plugins/ # Fresh plugins (3 files)
73
+ ├── clients/ # Client-side invoke proxy (3 files)
74
+ ├── commons/ # JWT, workflows
75
+ ├── utils/ # HTTP, cookies, timings, invoke helpers
76
+ ├── observability/ # OpenTelemetry instrumentation
77
+ ├── daemon/ # Sidecar/embedded daemon for dev
78
+ ├── dev/ # Dev server utilities
79
+ ├── hypervisor/ # Multi-site orchestration
80
+ └── scripts/ # Release, dev, bundle scripts
81
+ ```
82
+
83
+ ## Core Concepts
84
+
85
+ ### 1. Everything is a Resolvable
86
+
87
+ The fundamental unit in Deco is a **Resolvable** — an object with a `__resolveType` field pointing to a resolver:
88
+
89
+ ```typescript
90
+ // A resolvable stored in the decofile (CMS state)
91
+ {
92
+ "__resolveType": "site/loaders/productList.ts",
93
+ "query": "shoes",
94
+ "count": 12
95
+ }
96
+ ```
97
+
98
+ The engine recursively resolves all props, then invokes the matching resolver function.
99
+
100
+ ### 2. Blocks define the type system
101
+
102
+ Each block type (section, loader, action, etc.) defines how modules are adapted into resolvers:
103
+
104
+ - **section** → wraps a Preact component, adding SSR + optional data loading
105
+ - **loader** → wraps a function with caching, single-flight dedup, and tracing
106
+ - **action** → wraps a mutation function with tracing
107
+ - **handler** → produces an HTTP handler from config
108
+ - **matcher** → evaluates a predicate against request context
109
+ - **flag** → combines matchers with variants for feature flags
110
+ - **app** → bundles manifest + state + dependencies
111
+
112
+ ### 3. DecofileProvider manages state
113
+
114
+ The decofile is the CMS state — a `Record<string, Resolvable>`. Providers can be:
115
+ - **Filesystem** (`newFsProvider`) — reads from local `.json`/`.jsonl` files
116
+ - **Realtime** — connects to CMS websocket for live updates
117
+ - **JSON** — static in-memory state
118
+
119
+ ### 4. Request flow
120
+
121
+ ```
122
+ Request → Hono
123
+ → bindings middleware (RENDER_FN, GLOBALS)
124
+ → liveness probe (/deco/_liveness)
125
+ → state builder (prepareState, debug, echo)
126
+ → observability (OpenTelemetry trace/span)
127
+ → main middleware (CORS, headers, cache, segment)
128
+ → route matching:
129
+ /styles.css → tailwind CSS
130
+ /live/_meta → schema + manifest
131
+ /live/invoke/* → single/batch invoke
132
+ /deco/render → partial section render
133
+ * (catch-all) → page handler → resolve → render
134
+ ```
135
+
136
+ ### 5. Two rendering frameworks
137
+
138
+ | Framework | Islands | Partials | Usage |
139
+ |-----------|---------|----------|-------|
140
+ | **Fresh** | Preact islands | `<Partial>` + `f-partial` | Standard Deco sites |
141
+ | **HTMX** | None (no JS) | `hx-get/hx-swap` | Lightweight alternative |
142
+
143
+ ### 6. Invoke system
144
+
145
+ Client-side code calls server loaders/actions via the invoke API:
146
+
147
+ ```typescript
148
+ // Client-side (runtime.ts in a site)
149
+ import { proxy } from "@deco/deco/web";
150
+ const invoke = proxy<Manifest>();
151
+
152
+ // Calls POST /live/invoke/site/loaders/productList.ts
153
+ const products = await invoke["site/loaders/productList.ts"]({ query: "shoes" });
154
+ ```
155
+
156
+ ## Key Exports
157
+
158
+ ### `mod.ts` (main)
159
+ - `Context` — AsyncLocalStorage-based context
160
+ - `$live`, `initContext`, `newContext` — engine initialization
161
+ - `Deco`, `PageData` — runtime class and page data type
162
+ - `Block`, `BlockFunc`, `Resolvable`, `Resolved` — type system
163
+ - `asResolved`, `isDeferred`, `isResolvable` — resolution utilities
164
+ - `allowCorsFor` — CORS utility
165
+ - `JsonViewer`, `Framework` — components
166
+
167
+ ### `mod.web.ts` (client)
168
+ - `proxy`, `withManifest`, `forApp` — invoke proxy builders
169
+ - `readFromStream` — SSE stream reader
170
+ - `InvokeAwaiter` — chainable invoke proxy
171
+
172
+ ### `deco.ts` (context)
173
+ - `DecoContext` — site, siteId, deploymentId, platform, release, runtime
174
+ - `RequestContext` — signal, framework
175
+ - `Context.active()` — current context
176
+ - `Context.bind(ctx, fn)` — run fn with context
177
+
178
+ ## Dependencies
179
+
180
+ - **Runtime**: Deno, Fresh 1.6.8, Preact 10.23.1
181
+ - **Observability**: OpenTelemetry (api, sdk-trace, sdk-metrics, sdk-logs)
182
+ - **Framework**: Hono (HTTP router)
183
+ - **Deco ecosystem**: `@deco/durable`, `@deco/inspect-vscode`, `@deco/warp`
184
+ - **Std**: `@std/assert`, `@std/async`, `@std/crypto`, `@std/encoding`, `@std/http`
185
+ - **Compiler**: `jsx: "react-jsx"`, `jsxImportSource: "preact"`
@@ -0,0 +1,196 @@
1
+ # Block System (`blocks/`)
2
+
3
+ Blocks are the type system of Deco. Each block type defines how a module is adapted into a resolver, previewed, and invoked.
4
+
5
+ ## Block Interface
6
+
7
+ ```typescript
8
+ interface Block<TBlockModule> {
9
+ type: string; // manifest key: "sections", "loaders", etc.
10
+ introspect?: {
11
+ funcNames?: string[];
12
+ includeReturn?: boolean;
13
+ };
14
+ adapt?: (mod: TBlockModule, key: string) => Resolver | Resolver[];
15
+ decorate?: (mod: TBlockModule, key: string) => TBlockModule;
16
+ defaultDanglingRecover?: Resolver;
17
+ defaultPreview?: Resolver;
18
+ defaultInvoke?: Resolver;
19
+ }
20
+ ```
21
+
22
+ ## BlockModule Convention
23
+
24
+ Every block module can export:
25
+
26
+ | Export | Purpose |
27
+ |--------|---------|
28
+ | `default` | Main function (loader, action, component, handler factory) |
29
+ | `invoke` | Custom invocation handler (for `/live/invoke`) |
30
+ | `preview` / `Preview` | Admin preview component |
31
+ | `onBeforeResolveProps` | Transform props before resolution |
32
+
33
+ ## Block Types
34
+
35
+ ### Section (`section.ts`)
36
+
37
+ UI components that render on the page. The most common block type.
38
+
39
+ ```typescript
40
+ // type: "sections"
41
+ export default function MySection(props: Props) {
42
+ return <div>{props.title}</div>;
43
+ }
44
+
45
+ // With server-side data loading:
46
+ export const loader = async (props: Props, req: Request, ctx: AppContext) => {
47
+ const data = await fetchData(props);
48
+ return { ...props, data };
49
+ };
50
+
51
+ export default function MySection({ data, title }: LoaderReturn) {
52
+ return <div>{title}: {data}</div>;
53
+ }
54
+ ```
55
+
56
+ Features: wraps Preact component as resolver returning `PreactComponent`, supports `loader` for SSR, `action` for forms, ErrorBoundary + SectionContext wrapper.
57
+
58
+ ### Loader (`loader.ts`)
59
+
60
+ Data fetching functions with caching and single-flight dedup.
61
+
62
+ ```typescript
63
+ // type: "loaders"
64
+ export default async function myLoader(
65
+ props: Props,
66
+ req: Request,
67
+ ctx: AppContext
68
+ ): Promise<Product[]> {
69
+ return await ctx.invoke("vtex/loaders/productList.ts", props);
70
+ }
71
+ ```
72
+
73
+ Features: cached (single-flight), OpenTelemetry tracing, invocable via `/live/invoke`.
74
+
75
+ ### Action (`action.ts`)
76
+
77
+ Mutation functions (not cached).
78
+
79
+ ```typescript
80
+ // type: "actions"
81
+ export default async function addToCart(
82
+ props: { sku: string; quantity: number },
83
+ req: Request,
84
+ ctx: AppContext
85
+ ): Promise<Cart> {
86
+ return await ctx.invoke("vtex/actions/cart/addItems.ts", {
87
+ orderItems: [{ id: props.sku, quantity: props.quantity, seller: "1" }]
88
+ });
89
+ }
90
+ ```
91
+
92
+ ### Handler (`handler.ts`)
93
+
94
+ HTTP request handlers using a factory pattern.
95
+
96
+ ```typescript
97
+ // type: "handlers"
98
+ export default function proxy(config: { url: string }) {
99
+ return async (req: Request, ctx: ConnInfo): Promise<Response> => {
100
+ return await fetch(new URL(req.url).pathname, { ...config });
101
+ };
102
+ }
103
+ ```
104
+
105
+ Used for proxies, redirects, sitemaps, and custom routes.
106
+
107
+ ### Flag (`flag.ts`)
108
+
109
+ Feature flags with variant selection.
110
+
111
+ ```typescript
112
+ // type: "flags"
113
+ // Simple boolean flag:
114
+ export default function myFlag(config: { percentage: number }) {
115
+ return { name: "my-experiment", value: Math.random() < config.percentage };
116
+ }
117
+
118
+ // Multivariate:
119
+ export default function mvFlag(config: Config) {
120
+ return {
121
+ name: "checkout-v2",
122
+ variants: [
123
+ { value: "control", rule: { traffic: 0.5 } },
124
+ { value: "experiment", rule: { traffic: 0.5 } },
125
+ ],
126
+ };
127
+ }
128
+ ```
129
+
130
+ ### Matcher (`matcher.ts`)
131
+
132
+ Predicates for audience segmentation.
133
+
134
+ ```typescript
135
+ // type: "matchers"
136
+ export default function device(config: { mobile: boolean }) {
137
+ return (ctx: MatchContext): boolean => {
138
+ return ctx.device === "mobile" === config.mobile;
139
+ };
140
+ }
141
+ ```
142
+
143
+ Built-in matchers: MatchDevice, MatchCookie, MatchDate, MatchLocation, MatchHost, MatchRandom, MatchUserAgent, MatchSite, MatchMulti.
144
+
145
+ ### App (`app.ts`)
146
+
147
+ Container that bundles manifest + state + dependencies.
148
+
149
+ ```typescript
150
+ // type: "apps"
151
+ export default function MyApp(props: Props): App<Manifest, State> {
152
+ return {
153
+ manifest,
154
+ state: { /* clients, config */ },
155
+ dependencies: [otherApp(props)],
156
+ };
157
+ }
158
+ ```
159
+
160
+ `buildRuntime` processes the manifest, creating resolvers for each block module.
161
+
162
+ ### Page (`page.tsx`)
163
+
164
+ Like section but page-level. Same mechanism.
165
+
166
+ ### Workflow (`workflow.ts`)
167
+
168
+ Durable workflows using `@deco/durable`. Type: "workflows".
169
+
170
+ ### Function (`function.ts`)
171
+
172
+ Legacy loader format. Deprecated in favor of `loader.ts`.
173
+
174
+ ### Account (`account.ts`)
175
+
176
+ Platform configuration blocks. Returns account/config object.
177
+
178
+ ## Block Registration Flow
179
+
180
+ 1. `decoManifestBuilder()` scans directories matching block types
181
+ 2. `manifest.gen.ts` is generated with imports and block keys
182
+ 3. At startup, `buildRuntime()` processes each block:
183
+ - `block.adapt(mod, key)` for each module
184
+ - `block.decorate(mod, key)` applied before adapt
185
+ - Resolvers registered: `key`, `Preview@key`, `Invoke@key`
186
+ - `defaultDanglingRecover` registered per block type
187
+ 4. All resolvers passed to `ReleaseResolver`
188
+
189
+ ## Block Resolution Priority
190
+
191
+ When resolving `__resolveType`:
192
+ 1. Check `resolvables[type]` (decofile state) then recurse
193
+ 2. Check `resolvers[type]` (block resolvers) then invoke
194
+ 3. Check `overrides[type]` then redirect
195
+ 4. Fall back to `DanglingRecover@{blockType}` (StubSection)
196
+ 5. Throw `DanglingReference` error
@@ -0,0 +1,191 @@
1
+ # deco-cx/deco vs @decocms/start
2
+
3
+ Mapping between the original Deco framework (Fresh/Deno) and its TanStack/Node counterpart.
4
+
5
+ ## Architecture Comparison
6
+
7
+ ```
8
+ deco-cx/deco (Fresh/Deno) @decocms/start (TanStack/Node)
9
+ ───────────────────────── ──────────────────────────────
10
+ Deno runtime Node.js / Cloudflare Workers
11
+ Fresh 1.6.8 framework TanStack Start + Vite
12
+ Preact 10.23.1 React 18/19
13
+ Hono (internal router) TanStack Router (file-based)
14
+ manifest.gen.ts Explicit imports + admin protocol
15
+ DecofileProvider Admin SDK (CMS state fetching)
16
+ Resolution engine (Resolvable) Direct function calls
17
+ Block system (adapt/resolve) Pure async functions
18
+ @preact/signals @tanstack/react-store / React state
19
+ deno.json (import map) package.json + npm
20
+ ```
21
+
22
+ ## Module Mapping
23
+
24
+ ### Entry Points
25
+
26
+ | deco-cx/deco | @decocms/start | Notes |
27
+ |-------------|----------------|-------|
28
+ | `mod.ts` | `src/index.ts` | Main exports |
29
+ | `mod.web.ts` | Not needed | Client invoke is direct imports |
30
+ | `deco.ts` (Context) | Admin context/config | No AsyncLocalStorage pattern |
31
+ | `live.ts` | N/A (legacy) | — |
32
+ | `types.ts` | TypeScript types from packages | — |
33
+
34
+ ### Engine → Generic Resolver
35
+
36
+ Both frameworks now have a resolution engine, but `@decocms/start`'s is simpler and purpose-built:
37
+
38
+ ```typescript
39
+ // deco-cx/deco: full resolution engine with hints, single-flight, monitoring
40
+ // decofile state:
41
+ { "__resolveType": "vtex/loaders/productList.ts", "query": "shoes", "count": 12 }
42
+ // → engine.resolve() → find resolver → invoke with resolved props → hints → monitoring
43
+
44
+ // @decocms/start: generic recursive resolver (internalResolve)
45
+ // Same __resolveType decofile format, resolved via:
46
+ // 1. Check commerce loaders registry
47
+ // 2. Check decofile blocks
48
+ // 3. DanglingReference fallback (configurable)
49
+ // + Per-request memoization + depth protection (max 10)
50
+ ```
51
+
52
+ Key differences:
53
+ - `deco-cx/deco` has full-featured single-flight, hints, monitoring
54
+ - `@decocms/start` has simpler memoization + configurable error handlers (`setResolveErrorHandler`, `setDanglingReferenceHandler`)
55
+ - `@decocms/start` supports `select` field filtering on resolved values
56
+ - `@decocms/start` allows dynamically adding skip types via `addSkipResolveType()`
57
+
58
+ ### Blocks → Functions/Components
59
+
60
+ | deco Block | TanStack Equivalent |
61
+ |-----------|---------------------|
62
+ | Section block | React component (direct import) |
63
+ | Loader block (cached, single-flight) | Server function + React Query (with staleTime) |
64
+ | Action block | Server function + React Query mutation |
65
+ | Handler block | TanStack Router route handler |
66
+ | Flag block | Feature flag config (edge-level) |
67
+ | Matcher block | Middleware or route guard |
68
+ | App block | `configure*()` function (e.g., `configureVtex()`) |
69
+ | Workflow block | Background task (platform-specific) |
70
+
71
+ ### Runtime → TanStack Start
72
+
73
+ | deco Runtime | TanStack Start |
74
+ |-------------|---------------|
75
+ | Hono router | TanStack Router |
76
+ | Fresh middleware chain | TanStack Start middleware |
77
+ | `/live/invoke/*` | API routes or server functions |
78
+ | `/deco/render` | React Server Components or loader revalidation |
79
+ | `entrypoint.tsx` catch-all | `__root.tsx` + route tree |
80
+ | `Deco` class | Vite plugin + start config |
81
+
82
+ ### Hooks → React Equivalents
83
+
84
+ | deco Hook | TanStack Equivalent |
85
+ |-----------|---------------------|
86
+ | `useSection()` | React Query revalidation + state updates (stub in `@decocms/start`) |
87
+ | `usePartialSection()` | TanStack Router Link / navigate (stub in `@decocms/start`) |
88
+ | `useScript()` | `@decocms/start/sdk/useScript` — with lightweight minification + LRU cache |
89
+ | `useScriptAsDataURI()` | `@decocms/start/sdk/useScript` — same, data URI variant |
90
+ | `useDevice()` | `@decocms/start/sdk/useDevice` — server-side via User-Agent + RequestContext, also `detectDevice`, `checkMobile/Tablet/Desktop` |
91
+ | `useSetEarlyHints()` | Response headers in server middleware |
92
+
93
+ ### Plugins → Config
94
+
95
+ | deco Plugin | TanStack Equivalent |
96
+ |------------|---------------------|
97
+ | `plugins/deco.ts` (Fresh plugin) | `@decocms/start` Vite plugin + entry |
98
+ | `plugins/fresh.ts` (Tailwind + Deco) | Tailwind via Vite plugin |
99
+ | `plugins/styles.ts` (global CSS) | CSS in `__root.tsx` or global stylesheet |
100
+
101
+ ### Clients → Direct Imports
102
+
103
+ | deco Client | TanStack Equivalent |
104
+ |------------|---------------------|
105
+ | `proxy<Manifest>()` | Direct function imports |
106
+ | `invoke["key"](props)` | `await loaderFn(props)` or `/deco/invoke` with FormData/URLEncoded/JSON |
107
+ | `readFromStream()` | `fetch()` + ReadableStream |
108
+ | `formDataToProps()` | Built into invoke handler (auto-parses multipart/form-data and URL-encoded) |
109
+
110
+ ### Components → React Components
111
+
112
+ | deco Component | TanStack Equivalent |
113
+ |---------------|---------------------|
114
+ | `LiveControls.tsx` | `LiveControls.tsx` in `@decocms/start` (adapted) |
115
+ | `SectionContext` | React context per section |
116
+ | `ErrorBoundary` | React Error Boundary |
117
+ | `StubSection` | Fallback component |
118
+ | `JsonViewer` | JSON display component |
119
+
120
+ ## State Management Comparison
121
+
122
+ ### deco-cx/deco
123
+
124
+ ```
125
+ CMS Admin → publish → DecofileProvider.onChange()
126
+ → ReleaseResolver rebuilds
127
+ → New resolvables available
128
+ → Next request uses new state
129
+ ```
130
+
131
+ ### @decocms/start
132
+
133
+ ```
134
+ CMS Admin → publish → POST /.decofile (hot-reload)
135
+ → setBlocks() updates in-memory state
136
+ → Revision recomputed (content-hash)
137
+ → onChange listeners notified (meta cache invalidated)
138
+ → clearLoaderCache() ensures fresh data
139
+ → Edge cache purge (Cloudflare)
140
+ → Next request uses new state + fresh schema
141
+ ```
142
+
143
+ ## Rendering Comparison
144
+
145
+ ### deco-cx/deco (SSR + Islands)
146
+
147
+ ```
148
+ Request → Fresh handler
149
+ → Resolve page sections (engine)
150
+ → Preact renderToString (server)
151
+ → Hydrate islands only (client)
152
+ → Partial updates via useSection + /deco/render
153
+ ```
154
+
155
+ ### @decocms/start (SSR + Full Hydration)
156
+
157
+ ```
158
+ Request → TanStack Start handler
159
+ → Route loader runs (server function)
160
+ → React renderToString (server)
161
+ → Full hydration (client)
162
+ → Client-side navigation via TanStack Router
163
+ → Data updates via React Query revalidation
164
+ ```
165
+
166
+ ## Caching Comparison
167
+
168
+ | Aspect | deco-cx/deco | @decocms/start |
169
+ |--------|-------------|---------------|
170
+ | Loader cache | In-process single-flight + LRU | React Query staleTime + Cloudflare cache |
171
+ | Page cache | CDN + Deco edge | Cloudflare Workers cache API |
172
+ | Static assets | Fresh static serving | Vite build + CDN |
173
+ | Cache invalidation | DecofileProvider onChange | `setBlocks` → onChange listeners + `clearLoaderCache()` + edge purge |
174
+
175
+ ## Key Takeaways for Porting
176
+
177
+ 1. **Simpler resolution engine**: `@decocms/start` now has a generic recursive resolver (`internalResolve`) for `__resolveType`, but it's simpler than `deco-cx/deco`'s full engine (no hints, no single-flight). It resolves commerce loaders, decofile blocks, and has configurable fallback for dangling references.
178
+
179
+ 2. **No manifest**: Instead of auto-generated manifests with lazy imports, `@decocms/apps-start` uses explicit exports that sites import directly.
180
+
181
+ 3. **No islands architecture**: React hydrates everything. Optimize with React.lazy, Suspense, and code splitting instead.
182
+
183
+ 4. **Enhanced invoke**: The `/deco/invoke` endpoint now supports FormData, URL-encoded bodies, `?select=` filtering, batch execution, actions registration, and nested `__resolveType` resolution.
184
+
185
+ 5. **CMS integration**: `@decocms/start` provides the admin protocol (LiveControls, section editing) through its own SDK. Schema registries are dynamic (loaders + matchers registered at runtime).
186
+
187
+ 6. **Edge-first**: `@decocms/start` is designed for Cloudflare Workers, with caching handled at the edge rather than in-process.
188
+
189
+ 7. **Observability parity**: `@decocms/start` now has pluggable `TracerAdapter` + `MeterAdapter`, standardized `MetricNames`, and a `/deco/_health` endpoint with uptime, memory, cache stats, and request metrics.
190
+
191
+ 8. **Server-side device detection**: `useDevice()` works server-side via `RequestContext` + User-Agent parsing, matching `deco-cx/deco`'s functionality.