Release: v0.41.0-alpha.3#110
Conversation
- tools/autoflow/release.ts: skip release gates and deploy steps when CI=true - .github/workflows/autoflow-release.yml: drop gates and deploy jobs; rely on branch protection - tools/consumer-smoke.ts: include @openelement/protocol in local workspace smoke - docs/release/v0.41.0-alpha.2-plan.md: plan pure-ESM npm quality gates for alpha.3
…red surfaces (#62) Protocol surface and over-engineering cleanup for v0.41.0-alpha.1-cleanup patch. - Removes speculative protocol types while keeping protected surface intact. - Preserves SignalEngine abstraction per ADR-0109 P2. - Flattens OpenElementBuildContext phase tokens. - Removes dead DSD report pipeline, merges ssg-i18n into ssg-dynamic. - Cleans content nav writer exports and architecture contract less* guard. - Replaces tools/lib/walk.ts with @std/fs/walk. All local release gates pass (autoflow:ci 21/21).
- Generate ui manifest at build/test/pack time; remove runtime Deno.* usage. - Flatten lifecycle helpers (start/stop/transition) into app authoring. - Break core intra-package cycle via BindingRenderer interface. - Router data-context uses render-scoped stack. - Move app Vite plugin to @openelement/adapter-vite; make Preact adapter dynamic/peer. Co-authored-by: DevBot <devbot@openelement.dev>
* fix(core/content/ssg): address deferred alpha.1 review findings (#81) - Standardize import extensions to .js across packages/core/src - Remove nodeType === 0 production coupling; set fake fragment nodeType to 11 in tests - Restore globalThis.document after binding-activation and jsx-render-dom tests - Add content-helpers.test.ts for write-json, sitemap/plugin, fs-adapter - Import only cwd from node:process in ssg-render and build-postprocess * fix(content,core): address PR #84 robot nits - Import BufferEncoding via NodeJS namespace in fs-adapter.ts so the cast is type-safe without relying on a non-existent 'node:buffer' export. - Add comments to the restore-global-document tests documenting that they must remain the last test in each file. --------- Co-authored-by: DevBot <devbot@openelement.dev>
…heet (#86) Safari/WebKit does not support :host-context, so the dark-mode token rule was dropped entirely in shadow roots that adopted openPropsTokenSheet. Remove :host-context from the host sheet and add openPropsRootSheet, a :root variant for document-level adoption that cascades into every shadow DOM via custom-property inheritance. Closes #80 Co-authored-by: DevBot <devbot@openelement.dev>
* feat(ui): validate static subpath with open-button (#79) - Migrate open-button escapeAttr import from @openelement/core to @openelement/core/static - Add packages/ui/__tests__/static-subpath.test.ts * test(create): add @openelement/core/static alias in generated project test open-button now imports from @openelement/core/static; the create CLI workspace-test harness must alias that subpath or the generated project build fails during SSR bundle resolution. * fix(create): add @openelement/core/static alias to consumer-local.ts --------- Co-authored-by: DevBot <devbot@openelement.dev>
…/core/hydrate (#83) * feat(core/element): extract HydrationScope to @openelement/core/hydrate (#76) - Create HydrationScope value object in packages/core/src/hydration-scope.ts - Export HydrationScope from @openelement/core/hydrate - Refactor OpenElement to own a single #hydrationScope - Refactor open-element-hydration.ts and open-element-render.ts to operate on scope - Add hydration-scope.test.ts with fake DOM and isolation tests - Update subpath-exports.test.ts for HydrationScope export - Update STATUS.md and VERSION_PLAN.md for v0.41.0-alpha.2 * fix(core,element): address HydrationScope robot review findings - Add HydrationScope.reset() to clear effects/events without deactivating the scope; use it before re-render/re-hydrate. - Fix critical bug in hydrateExistingDom: scope.dispose() was called before scope.hydrate(), which made hydrate() a no-op. Replace with scope.reset(). - Use scope.dispose() in OpenElement.disconnectedCallback for true lifecycle cleanup instead of disposeRenderBindings(). - Remove duplicate disposeRenderBindings() helper; disposal now lives in the scope. - Remove unused disposeScope() helper and VNodeCacheAccess type export. - Drop unused render callback from OpenElement's HydrationScope. - Normalize import extension in hydrate.ts (.ts -> .js). * fix(hydration): fmt/lint/arch and consumer-local alias for HydrationScope * style: format hydration-scope.test and open-element-render for fmt:check * ci: trigger rebuild after format fixes --------- Co-authored-by: DevBot <devbot@openelement.dev>
- Add factory constructors for all descriptor kinds in binding-descriptor.ts - Replace central switch in applyBindingDescriptor with internal Map registry - Add registerBindingKind for custom binding kinds - Update jsx-render-dom.ts, hydration-scope.ts, event-hydration.ts to use factories - Re-export factories and registerBindingKind from core/csr/hydrate entry points - Add custom binding kind test Co-authored-by: DevBot <devbot@openelement.dev>
- Cache cacheAccess getter in private field to fix object identity - Remove dead VNodeCacheAccess.get() method - Mark VNodeCacheAccess and cacheAccess as @internal - Normalize import extensions to .js in hydration-scope.ts - Fix --blue-10 -> --teal-10 typo in dark-mode token block Co-authored-by: DevBot <devbot@openelement.dev>
…90) * fix(core): binding layer cleanup - factories, registry, types (#90) - Remove _root dead param from commitBindings - Add bindHtml factory for signal-html descriptors - Add overwrite warning to registerBindingKind - Remove dead keyFn field from ListBindingDescriptor - Narrow condition type to Signal<boolean> | boolean - Narrow items type to Signal<unknown[]> | unknown[] - Use bindHtml factory in collectPropBindings - Re-export bindHtml from core/csr/hydrate entry points * docs: add comments documenting narrowed type casts * fix(core): revert narrowed factory types per bot review Widen bindConditional/bindList factory signatures back to Signal<unknown> | unknown to match runtime coercion in applyConditional/applyList --------- Co-authored-by: DevBot <devbot@openelement.dev>
* chore: bump versions to 0.41.0-alpha.2 and update roadmap (#82) - Bump all 11 packages from 0.41.0-alpha.1 to 0.41.0-alpha.2 - Mark v0.41.0-alpha.2 as Shipped in ROADMAP.md - Add completion note * fix: update PACKAGE_VERSION and docs for alpha.2 (#82) - Bump PACKAGE_VERSION in tools/project-constants.ts to 0.41.0-alpha.2 - Update README.md, README.zh.md, PROJECT_WORKFLOW.md with alpha.2 * fix: update ACTIVE_VERSION and www route version refs for alpha.2 * fix: update getting-started.tsx with alpha.2 version ref --------- Co-authored-by: DevBot <devbot@openelement.dev>
* docs: fix stale version refs in ROADMAP header, README Current Line, PACKAGE_SURFACE, design README * docs: fix remaining stale version refs and PACKAGE_SURFACE protocol row - Update OPENELEMENT_VERSION constant to v0.41.0-alpha.2 - Fix hardcoded alpha.1 strings in architecture, apilist, examples routes - Add @openelement/protocol to PACKAGE_SURFACE table (11-package) * docs: fix two more stale v0.41.0-alpha.1 refs * docs: fix 14-to-10 -> 14-to-11 in PACKAGE_SURFACE.md --------- Co-authored-by: DevBot <devbot@openelement.dev>
- Remove dead _hydrateSignals() method and unused hydrateSignals import - Fix inconsistent DOM clearing: shadow root now clears before null check - Import eventTypeFromProp from event-marker.js instead of event-hydration.js - Remove dead 'key' field from StaticAttrBindingDescriptor interface and factory - Remove dangling comment in protocol/manifest.ts - Update stale comments referencing _hydrateSignals Co-authored-by: DevBot <devbot@openelement.dev>
1. CSR className/class props use bindAttr (signal-attr) instead of bindClass 2. collectHydrationBindings accepts lifecycle param directly 3. Make VNodeCacheAccess non-exported (file-private) 4. Add HydrationScope.createLifecycle() method 5. Remove duplicate bindHydrateEvents re-export from hydrate.ts 6. Restore framework.js barrel in protocol/src/index.ts 7. Document AbortSignal absence in open-element-render.ts 8. Make SignalRenderBindingDescriptor.lifecycle optional 9. Reject null bytes in resolveDynamicRoutePath 10. Replace ponytail comment with normal comment
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Zhi <freemanzheng@hotmail.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Zhi <freemanzheng@hotmail.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Zhi <freemanzheng@hotmail.com>
- Collapse identical if/else branches in collectPropBindings - Remove unused _effectDisposers / _eventCleanups getters - Document SignalClassBindingDescriptor as DSD-only
…t, constructor init - reset() no longer gates on #active so reconnection can re-hydrate - registerDispose uses AbortSignal OR disposers Set, not both (avoid double-dispose) - Drop @internal from DANGEROUS_KEYS barrel export - Move HydrationScope construction into OpenElement constructor with super() call
…vate, hoist inline import
- Replace cacheAccess getter + VNodeCacheAccess interface with setCachedVNode method
- Remove export from hydrateSignals (only used in same module)
- Hoist Signal import type in open-element-render.ts to top level
- Make bindRender lifecycle parameter required (no default {})
- reset() now sets #active = true so disconnect/reconnect can re-hydrate - Add comment documenting test mock ordering requirement
…ktop only in alpha.5
- Move inline fixture strings to standalone files under tools/third-party-wc-smoke/app/ - Add allPackageAliases() to tools/lib/package-graph.ts - Use allPackageAliases() in both third-party-wc-smoke.ts and consumer-local.ts - Reduces smoke test from 551 → 253 lines (54% reduction)
Deploying openelement with
|
| Latest commit: |
fb8265d
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://b1b4fa8c.lessjs.pages.dev |
| Branch Preview URL: | https://dev.lessjs.pages.dev |
|
Now I have a thorough understanding of all 42 changed files. Here's my review. PR Review: v0.41.0-alpha.3 — Cross-Framework Web Components IntegrationBugs1. if (phase === 2 && !this.completed.has(3)) {
throw new Error('Phase 2 requires Phase 3 to be completed first');
}Phase 2 is the client island build, Phase 3 is SSG rendering. Phase 2 cannot require Phase 3 — that's backwards. The intent reads like Phase 3 requires Phase 2 (SSG rendering depends on the client bundle being built). This condition should either be removed or corrected to 2. After stripping 3. Module-level global mutation leaks across test files (jsx-render-dom.test.ts:11-12) const _savedDocument = (globalThis as ...).document;
(globalThis as ...).document = new TestDocument();The mock Over-engineering / Unnecessary Abstraction4. These three one-liner methods do nothing beyond direct assignment — yet 5. registerPlugin(name: string, instance: unknown): void {
this.plugins[name] = instance;
}The 6. Fragile path slicing in cleanup (check-package-artifacts.ts:234) await Deno.remove(packageRoot.slice(0, packageRoot.length - '/package'.length), { recursive: true });String-length arithmetic for path manipulation is brittle. Use Readability / Maintenance7. Hardcoded version anchors make release brittle (autoflow/release.ts:364-409)
8.
9.
Style / Nits10.
11. Unnecessary empty return Deno.serve({ port: 0, onListen: () => {} }, async (request) => {The 12. The Summary
The substantive architecture work (WC interop, ESM gates, test consolidation) looks solid. The main risk items are the inverted phase ordering check (will cause runtime failures if |
- Remove inverted phase ordering check in markComplete - Fix stripComments URL mangling in check-package-artifacts - Replace module-level document mutation with setupMockDocument() - Remove unused recordPhase*Fact wrappers - Tighten registerPlugin generic type - Replace fragile path slicing with dirname()
|
Here's my review, verified against the actual source files: PR Review: v0.41.0-alpha.3Disposition: Mostly clean. One real bug, several readability issues worth fixing. Several bot review findings were already addressed in the actual code (markComplete ordering, stripComments URL mangling, registerPlugin typing, fragile path slicing are all correct). Bugs1. Module-level
Readability / Maintenance2. Hardcoded version anchors will silently miss targets —
3. Helper functions declared after control flow —
Nits4. Empty Deno.serve({ port: 0, onListen: () => {} }, async (request) => {The no-op callback is unnecessary. 5. The Summary
The architecture work (BuildContext deepening, WC interop smoke tests, ESM gates, test consolidation into test-utils.ts) is solid. The |
|
All files reviewed. Here's my independent assessment. Earlier bot reviews had several false positives; the actual code is cleaner than reported. PR Review: v0.41.0-alpha.3Disposition: The architecture is solid. One real edge-case bug in the comment scanner, two maintainability issues, and a few nits. Bugs1. return source
.replace(/\/\*[\s\S]*?\*\//g, (match) => ' '.repeat(match.length))
.replace(/\/\/.*/g, '');After block-comment replacement with spaces, a line like Readability / Maintenance2. Hardcoded version anchors will silently miss targets — Every 3. Helper functions declared after
Nits4. Unnecessary empty Deno.serve({ port: 0, onListen: () => {} }, async (request) => {
5. The Previously-reported issues that are already correct
Summary
The core work — BuildContext deepening, WC interop smoke tests, ESM artifact gates, and test consolidation into |
app→adapter-vite→app creates a cycle that breaks graph:check. Keep adapter-vite as the canonical Vite entry; update docs accordingly.
|
Here's my independent review of the current code (post-fix commits PR Review: v0.41.0-alpha.3Disposition: Clean. The BugsNone. Readability / Maintenance1. Helper functions declared after
2. Hardcoded version anchors require manual bump per release — Every Nits3. Empty Deno.serve({ port: 0, onListen: () => {} }, async (request) => {
4. The Summary
The cross-framework WC integration, |
- Document stripComments edge case as extremely unlikely - Remove empty onListen callback in smoke test - Move helper functions before control flow in consumer-local.ts
PR Review: v0.41.0-alpha.3Disposition: Clean. The architecture is solid, and all substantive issues from the earlier bot reviews have been addressed in the actual code. Two maintainability nits remain. BugsNone. All previously-flagged issues are already correct in the code:
Readability / Maintenance1. Helper functions declared after their first call site —
2. Hardcoded version anchors require bump per release — Every Nits3. ssrNoExternal: (string | { __type: 'RegExp'; source: string; flags: string })[] = [];Passing an actual Summary
The core work — WC interop smoke tests, ESM artifact gates ( |
|
Here's my review after reading the actual source files (focusing on the diff): PR Review: v0.41.0-alpha.3Disposition: Clean. All substantive bugs flagged in earlier bot reviews are already correct in the code. Two maintainability issues and one nit remain. BugsNone. Verified against source:
Readability / Maintenance1. Hardcoded version anchors require manual bump per release — Every 2. Helper functions declared after exit logic —
Nit3. ssrNoExternal: (string | { __type: 'RegExp'; source: string; flags: string })[] = [];Passing a real |
|
Here's my review against the actual source files (previous bot reviews had several false positives I've verified): PR Review: v0.41.0-alpha.3Disposition: Clean. No bugs found. The cross-framework WC integration, ESM artifact gate, Previously-Reported Issues That Are Already CorrectAll three prior reviews flagged items that don't exist in the source:
Maintainability1. Helper functions declared after
2. Hardcoded version anchors require manual bump per release — Every Type-Safety Gap3. registerPlugin(name: string, instance: unknown): void;The concrete implementation ( registerPlugin<K extends keyof OpenElementBuildContextLike['plugins']>(
name: K, instance: OpenElementBuildContextLike['plugins'][K]
): void;Nits4. The implementation strips brackets and matches only attribute presence, unlike real DOM 5. Passing an actual Summary
The architecture is solid. Approve as-is; the maintainability items are low-priority improvements for the next cycle. |
PR Review: v0.41.0-alpha.3Disposition: Clean. All substantive bugs flagged in earlier bot reviews are already correct in the source. Two maintainability items and two nits remain. Previously-Reported Issues — Verified Correct
Maintenance1. Hardcoded version anchors require manual bump per release — Every 2. Helper functions declared after first call site —
Type Safety3. Protocol registerPlugin(name: string, instance: Record<string, unknown>): void;The concrete class uses Nits4. The JSDoc warns callers to use Summary
The core work — WC interop smoke tests, ESM artifact gates, |
…registerPlugin to unknown
|
Now I have a thorough understanding of the code. Here's my independent review: PR Review: v0.41.0-alpha.3Disposition: Clean. The architecture work is solid — WC interop, ESM artifact gates, Verified False Positives from Prior Bot Reviews
Maintainability1. Hardcoded version anchors require manual bump per release — Every 2. ssrNoExternal: (string | { __type: 'RegExp'; source: string; flags: string })[] = [];The JSDoc warns callers to use the plain-object form, but passing an actual Nits3. Protocol registerPlugin(name: string, instance: unknown): void;The concrete class at 4. Documented in the ponytail comment on lines 435-436. Adequate for current tests but will silently return wrong results for tag selectors or Summary
Approve as-is. The maintenance items can be addressed in a follow-up cycle. |
|
Review complete. No bugs found; the three documented items (hardcoded release anchors, RegExp serialization, limited querySelectorAll) are acknowledged in-code with ponytail/JSDoc comments and can be addressed in a follow-up cycle. |
* ci(release): remove duplicate gates and deploy job from release workflow - tools/autoflow/release.ts: skip release gates and deploy steps when CI=true - .github/workflows/autoflow-release.yml: drop gates and deploy jobs; rely on branch protection - tools/consumer-smoke.ts: include @openelement/protocol in local workspace smoke - docs/release/v0.41.0-alpha.2-plan.md: plan pure-ESM npm quality gates for alpha.3 * cleanup(protocol): remove speculative protocol types and over-engineered surfaces (#62) Protocol surface and over-engineering cleanup for v0.41.0-alpha.1-cleanup patch. - Removes speculative protocol types while keeping protected surface intact. - Preserves SignalEngine abstraction per ADR-0109 P2. - Flattens OpenElementBuildContext phase tokens. - Removes dead DSD report pipeline, merges ssg-i18n into ssg-dynamic. - Cleans content nav writer exports and architecture contract less* guard. - Replaces tools/lib/walk.ts with @std/fs/walk. All local release gates pass (autoflow:ci 21/21). * cleanup(runtime): boundary and core architecture cleanup (#59) - Generate ui manifest at build/test/pack time; remove runtime Deno.* usage. - Flatten lifecycle helpers (start/stop/transition) into app authoring. - Break core intra-package cycle via BindingRenderer interface. - Router data-context uses render-scoped stack. - Move app Vite plugin to @openelement/adapter-vite; make Preact adapter dynamic/peer. Co-authored-by: DevBot <devbot@openelement.dev> * cleanup(verifiability): release hygiene and type verification (#61) (#64) cleanup(verifiability): release hygiene and type verification (#61) * fix: post-audit fixes for alpha.1-cleanup review findings (#75) fix: post-audit fixes for alpha.1-cleanup review findings (#65-#74) plus CI typecheck fix * [v0.41.0-alpha.2] Deferred alpha.1 review cleanup (#84) * fix(core/content/ssg): address deferred alpha.1 review findings (#81) - Standardize import extensions to .js across packages/core/src - Remove nodeType === 0 production coupling; set fake fragment nodeType to 11 in tests - Restore globalThis.document after binding-activation and jsx-render-dom tests - Add content-helpers.test.ts for write-json, sitemap/plugin, fs-adapter - Import only cwd from node:process in ssg-render and build-postprocess * fix(content,core): address PR #84 robot nits - Import BufferEncoding via NodeJS namespace in fs-adapter.ts so the cast is type-safe without relying on a non-existent 'node:buffer' export. - Add comments to the restore-global-document tests documenting that they must remain the last test in each file. --------- Co-authored-by: DevBot <devbot@openelement.dev> * fix(ui): remove :host-context from token sheet and add openPropsRootSheet (#86) Safari/WebKit does not support :host-context, so the dark-mode token rule was dropped entirely in shadow roots that adopted openPropsTokenSheet. Remove :host-context from the host sheet and add openPropsRootSheet, a :root variant for document-level adoption that cascades into every shadow DOM via custom-property inheritance. Closes #80 Co-authored-by: DevBot <devbot@openelement.dev> * [v0.41.0-alpha.2] Validate static subpath with open-button (#85) * feat(ui): validate static subpath with open-button (#79) - Migrate open-button escapeAttr import from @openelement/core to @openelement/core/static - Add packages/ui/__tests__/static-subpath.test.ts * test(create): add @openelement/core/static alias in generated project test open-button now imports from @openelement/core/static; the create CLI workspace-test harness must alias that subpath or the generated project build fails during SSR bundle resolution. * fix(create): add @openelement/core/static alias to consumer-local.ts --------- Co-authored-by: DevBot <devbot@openelement.dev> * [v0.41.0-alpha.2] Candidate 3: Extract HydrationScope to @openelement/core/hydrate (#83) * feat(core/element): extract HydrationScope to @openelement/core/hydrate (#76) - Create HydrationScope value object in packages/core/src/hydration-scope.ts - Export HydrationScope from @openelement/core/hydrate - Refactor OpenElement to own a single #hydrationScope - Refactor open-element-hydration.ts and open-element-render.ts to operate on scope - Add hydration-scope.test.ts with fake DOM and isolation tests - Update subpath-exports.test.ts for HydrationScope export - Update STATUS.md and VERSION_PLAN.md for v0.41.0-alpha.2 * fix(core,element): address HydrationScope robot review findings - Add HydrationScope.reset() to clear effects/events without deactivating the scope; use it before re-render/re-hydrate. - Fix critical bug in hydrateExistingDom: scope.dispose() was called before scope.hydrate(), which made hydrate() a no-op. Replace with scope.reset(). - Use scope.dispose() in OpenElement.disconnectedCallback for true lifecycle cleanup instead of disposeRenderBindings(). - Remove duplicate disposeRenderBindings() helper; disposal now lives in the scope. - Remove unused disposeScope() helper and VNodeCacheAccess type export. - Drop unused render callback from OpenElement's HydrationScope. - Normalize import extension in hydrate.ts (.ts -> .js). * fix(hydration): fmt/lint/arch and consumer-local alias for HydrationScope * style: format hydration-scope.test and open-element-render for fmt:check * ci: trigger rebuild after format fixes --------- Co-authored-by: DevBot <devbot@openelement.dev> * [v0.41.0-alpha.2] Candidate 1: Split renderer from activation layer (#77) - jsx-render-dom.ts now emits BindingDescriptors and commits them via commitBindings() - Move Show/For effect lifecycle into binding-activation.ts as conditional/list bindings - Add commitBindings export to core/csr/hydrate entry points Co-authored-by: DevBot <devbot@openelement.dev> * [v0.41.0-alpha.2] Candidate 2: BindingDescriptor registry (#78) - Add factory constructors for all descriptor kinds in binding-descriptor.ts - Replace central switch in applyBindingDescriptor with internal Map registry - Add registerBindingKind for custom binding kinds - Update jsx-render-dom.ts, hydration-scope.ts, event-hydration.ts to use factories - Re-export factories and registerBindingKind from core/csr/hydrate entry points - Add custom binding kind test Co-authored-by: DevBot <devbot@openelement.dev> * docs: mark v0.41.0-alpha.2 workstreams complete * fix(core,ui): polish HydrationScope and fix token typo (closes #89) - Cache cacheAccess getter in private field to fix object identity - Remove dead VNodeCacheAccess.get() method - Mark VNodeCacheAccess and cacheAccess as @internal - Normalize import extensions to .js in hydration-scope.ts - Fix --blue-10 -> --teal-10 typo in dark-mode token block Co-authored-by: DevBot <devbot@openelement.dev> * fix(core): binding layer cleanup - factories, registry, types (closes #90) * fix(core): binding layer cleanup - factories, registry, types (#90) - Remove _root dead param from commitBindings - Add bindHtml factory for signal-html descriptors - Add overwrite warning to registerBindingKind - Remove dead keyFn field from ListBindingDescriptor - Narrow condition type to Signal<boolean> | boolean - Narrow items type to Signal<unknown[]> | unknown[] - Use bindHtml factory in collectPropBindings - Re-export bindHtml from core/csr/hydrate entry points * docs: add comments documenting narrowed type casts * fix(core): revert narrowed factory types per bot review Widen bindConditional/bindList factory signatures back to Signal<unknown> | unknown to match runtime coercion in applyConditional/applyList --------- Co-authored-by: DevBot <devbot@openelement.dev> * chore: bump versions to 0.41.0-alpha.2 and update docs (#82) * chore: bump versions to 0.41.0-alpha.2 and update roadmap (#82) - Bump all 11 packages from 0.41.0-alpha.1 to 0.41.0-alpha.2 - Mark v0.41.0-alpha.2 as Shipped in ROADMAP.md - Add completion note * fix: update PACKAGE_VERSION and docs for alpha.2 (#82) - Bump PACKAGE_VERSION in tools/project-constants.ts to 0.41.0-alpha.2 - Update README.md, README.zh.md, PROJECT_WORKFLOW.md with alpha.2 * fix: update ACTIVE_VERSION and www route version refs for alpha.2 * fix: update getting-started.tsx with alpha.2 version ref --------- Co-authored-by: DevBot <devbot@openelement.dev> * docs: fix stale version refs found by bot review of #94 * docs: fix stale version refs in ROADMAP header, README Current Line, PACKAGE_SURFACE, design README * docs: fix remaining stale version refs and PACKAGE_SURFACE protocol row - Update OPENELEMENT_VERSION constant to v0.41.0-alpha.2 - Fix hardcoded alpha.1 strings in architecture, apilist, examples routes - Add @openelement/protocol to PACKAGE_SURFACE table (11-package) * docs: fix two more stale v0.41.0-alpha.1 refs * docs: fix 14-to-10 -> 14-to-11 in PACKAGE_SURFACE.md --------- Co-authored-by: DevBot <devbot@openelement.dev> * fix: resolve bot review findings from PR #96 (dev→main) - Remove dead _hydrateSignals() method and unused hydrateSignals import - Fix inconsistent DOM clearing: shadow root now clears before null check - Import eventTypeFromProp from event-marker.js instead of event-hydration.js - Remove dead 'key' field from StaticAttrBindingDescriptor interface and factory - Remove dangling comment in protocol/manifest.ts - Update stale comments referencing _hydrateSignals Co-authored-by: DevBot <devbot@openelement.dev> * fix: address all 10 PR #99 bot review findings 1. CSR className/class props use bindAttr (signal-attr) instead of bindClass 2. collectHydrationBindings accepts lifecycle param directly 3. Make VNodeCacheAccess non-exported (file-private) 4. Add HydrationScope.createLifecycle() method 5. Remove duplicate bindHydrateEvents re-export from hydrate.ts 6. Restore framework.js barrel in protocol/src/index.ts 7. Document AbortSignal absence in open-element-render.ts 8. Make SignalRenderBindingDescriptor.lifecycle optional 9. Reject null bytes in resolveDynamicRoutePath 10. Replace ponytail comment with normal comment * Potential fix for pull request finding 'Use of returnless function' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Zhi <freemanzheng@hotmail.com> * Potential fix for pull request finding 'Use of returnless function' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Zhi <freemanzheng@hotmail.com> * Potential fix for pull request finding 'Use of returnless function' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Zhi <freemanzheng@hotmail.com> * fix: collapse dead if/else, remove unused getters, add signal-class doc - Collapse identical if/else branches in collectPropBindings - Remove unused _effectDisposers / _eventCleanups getters - Document SignalClassBindingDescriptor as DSD-only * fix: reset() ungated, registerDispose exclusive, DANGEROUS_KEYS export, constructor init - reset() no longer gates on #active so reconnection can re-hydrate - registerDispose uses AbortSignal OR disposers Set, not both (avoid double-dispose) - Drop @internal from DANGEROUS_KEYS barrel export - Move HydrationScope construction into OpenElement constructor with super() call * fix: replace cacheAccess with setCachedVNode, make hydrateSignals private, hoist inline import - Replace cacheAccess getter + VNodeCacheAccess interface with setCachedVNode method - Remove export from hydrateSignals (only used in same module) - Hoist Signal import type in open-element-render.ts to top level - Make bindRender lifecycle parameter required (no default {}) * fix: reset() reactivates scope after dispose, doc test mock leak - reset() now sets #active = true so disconnect/reconnect can re-hydrate - Add comment documenting test mock ordering requirement * fix(test): wrap mock document in per-test setup/teardown to prevent cross-file leaks * fix: add @internal annotation to DANGEROUS_KEYS barrel export * fix: remove DANGEROUS_KEYS from barrel, add ShadowRoot stub restore * fix(release): accept semver pre-release suffix in parseSemver * fix: add @internal to DANGEROUS_KEYS in static.ts, fix greedy regex * fix(release): use --allow-dirty for deno pack in release mode deno fmt may touch files outside the staged bump list, making the worktree dirty. This is safe in CI where changes are expected. * fix(release): skip already-published packages on E403 * docs: add architecture review candidates to alpha.3 plan (#107-#109) * docs: reorganize alpha.4/5 — Preact island proof to alpha.4, Deno Desktop only in alpha.5 * feat(alpha3): add web components artifact gates * refactor(alpha.3): extract smoke fixtures to files, share alias logic - Move inline fixture strings to standalone files under tools/third-party-wc-smoke/app/ - Add allPackageAliases() to tools/lib/package-graph.ts - Use allPackageAliases() in both third-party-wc-smoke.ts and consumer-local.ts - Reduces smoke test from 551 → 253 lines (54% reduction) * feat(alpha.3): complete architecture candidates #107-#109 - #107: Create @openelement/app/vite as canonical Vite entry - #108: Deepen BuildContext with recordPhase* and registerPlugin methods - #109: Consolidate test DOM harness into test-utils.ts (-619 lines) - Update alpha.3 plan checkboxes to mark all workstreams complete * fix(alpha.3): address PR #110 bot review findings - Remove inverted phase ordering check in markComplete - Fix stripComments URL mangling in check-package-artifacts - Replace module-level document mutation with setupMockDocument() - Remove unused recordPhase*Fact wrappers - Tighten registerPlugin generic type - Replace fragile path slicing with dirname() * fix(test): wrap jsx-render-dom tests in withMockDocument for test isolation * fix(alpha.3): remove app/vite re-export to break dependency cycle app→adapter-vite→app creates a cycle that breaks graph:check. Keep adapter-vite as the canonical Vite entry; update docs accordingly. * fix(alpha.3): clear remaining bot review issues - Document stripComments edge case as extremely unlikely - Remove empty onListen callback in smoke test - Move helper functions before control flow in consumer-local.ts * docs: clarify ssrNoExternal RegExp serialization contract * docs: note hardcoded version anchors in release.ts as ponytail debt * fix(alpha.3): tighten registerPlugin protocol type, doc querySelectorAll limitation * fix(alpha.3): move helpers to top of consumer-local, revert protocol registerPlugin to unknown * fix: update arch:check allowlist for sitemap registerPlugin * fix(release): update version anchors from 0.40.8 to 0.41.0-alpha.2 * docs: mark alpha.3 as Shipped, update alpha.5 to Deno Desktop * feat(alpha.4): add hydrateOpenElement client runtime to core/hydrate * feat(alpha.4): add Fresh example with openElement + Preact island * feat(alpha.4): complete remaining tasks - smoke test, docs, plan update - Preact island smoke test (18 tests covering SSR, props, signals, lifecycle) - Fresh integration docs (docs/integrations/open-element-in-fresh.md) - Alpha.4 plan checkboxes updated (15 items marked complete) - Fresh example now uses hydrateOpenElement from core/hydrate * fix(alpha.4): use real hydrateOpenElement, format Fresh files * fix alpha4 ci review issues * fix alpha4 review followups * fix alpha4 final review gaps * fix alpha4 review docs and preact proof * fix alpha4 test stub cleanup * docs: mark alpha.4 release workflow items as done --------- Signed-off-by: Zhi <freemanzheng@hotmail.com> Co-authored-by: DevBot <devbot@openelement.dev> Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* ci(release): remove duplicate gates and deploy job from release workflow - tools/autoflow/release.ts: skip release gates and deploy steps when CI=true - .github/workflows/autoflow-release.yml: drop gates and deploy jobs; rely on branch protection - tools/consumer-smoke.ts: include @openelement/protocol in local workspace smoke - docs/release/v0.41.0-alpha.2-plan.md: plan pure-ESM npm quality gates for alpha.3 * cleanup(protocol): remove speculative protocol types and over-engineered surfaces (#62) Protocol surface and over-engineering cleanup for v0.41.0-alpha.1-cleanup patch. - Removes speculative protocol types while keeping protected surface intact. - Preserves SignalEngine abstraction per ADR-0109 P2. - Flattens OpenElementBuildContext phase tokens. - Removes dead DSD report pipeline, merges ssg-i18n into ssg-dynamic. - Cleans content nav writer exports and architecture contract less* guard. - Replaces tools/lib/walk.ts with @std/fs/walk. All local release gates pass (autoflow:ci 21/21). * cleanup(runtime): boundary and core architecture cleanup (#59) - Generate ui manifest at build/test/pack time; remove runtime Deno.* usage. - Flatten lifecycle helpers (start/stop/transition) into app authoring. - Break core intra-package cycle via BindingRenderer interface. - Router data-context uses render-scoped stack. - Move app Vite plugin to @openelement/adapter-vite; make Preact adapter dynamic/peer. Co-authored-by: DevBot <devbot@openelement.dev> * cleanup(verifiability): release hygiene and type verification (#61) (#64) cleanup(verifiability): release hygiene and type verification (#61) * fix: post-audit fixes for alpha.1-cleanup review findings (#75) fix: post-audit fixes for alpha.1-cleanup review findings (#65-#74) plus CI typecheck fix * [v0.41.0-alpha.2] Deferred alpha.1 review cleanup (#84) * fix(core/content/ssg): address deferred alpha.1 review findings (#81) - Standardize import extensions to .js across packages/core/src - Remove nodeType === 0 production coupling; set fake fragment nodeType to 11 in tests - Restore globalThis.document after binding-activation and jsx-render-dom tests - Add content-helpers.test.ts for write-json, sitemap/plugin, fs-adapter - Import only cwd from node:process in ssg-render and build-postprocess * fix(content,core): address PR #84 robot nits - Import BufferEncoding via NodeJS namespace in fs-adapter.ts so the cast is type-safe without relying on a non-existent 'node:buffer' export. - Add comments to the restore-global-document tests documenting that they must remain the last test in each file. --------- Co-authored-by: DevBot <devbot@openelement.dev> * fix(ui): remove :host-context from token sheet and add openPropsRootSheet (#86) Safari/WebKit does not support :host-context, so the dark-mode token rule was dropped entirely in shadow roots that adopted openPropsTokenSheet. Remove :host-context from the host sheet and add openPropsRootSheet, a :root variant for document-level adoption that cascades into every shadow DOM via custom-property inheritance. Closes #80 Co-authored-by: DevBot <devbot@openelement.dev> * [v0.41.0-alpha.2] Validate static subpath with open-button (#85) * feat(ui): validate static subpath with open-button (#79) - Migrate open-button escapeAttr import from @openelement/core to @openelement/core/static - Add packages/ui/__tests__/static-subpath.test.ts * test(create): add @openelement/core/static alias in generated project test open-button now imports from @openelement/core/static; the create CLI workspace-test harness must alias that subpath or the generated project build fails during SSR bundle resolution. * fix(create): add @openelement/core/static alias to consumer-local.ts --------- Co-authored-by: DevBot <devbot@openelement.dev> * [v0.41.0-alpha.2] Candidate 3: Extract HydrationScope to @openelement/core/hydrate (#83) * feat(core/element): extract HydrationScope to @openelement/core/hydrate (#76) - Create HydrationScope value object in packages/core/src/hydration-scope.ts - Export HydrationScope from @openelement/core/hydrate - Refactor OpenElement to own a single #hydrationScope - Refactor open-element-hydration.ts and open-element-render.ts to operate on scope - Add hydration-scope.test.ts with fake DOM and isolation tests - Update subpath-exports.test.ts for HydrationScope export - Update STATUS.md and VERSION_PLAN.md for v0.41.0-alpha.2 * fix(core,element): address HydrationScope robot review findings - Add HydrationScope.reset() to clear effects/events without deactivating the scope; use it before re-render/re-hydrate. - Fix critical bug in hydrateExistingDom: scope.dispose() was called before scope.hydrate(), which made hydrate() a no-op. Replace with scope.reset(). - Use scope.dispose() in OpenElement.disconnectedCallback for true lifecycle cleanup instead of disposeRenderBindings(). - Remove duplicate disposeRenderBindings() helper; disposal now lives in the scope. - Remove unused disposeScope() helper and VNodeCacheAccess type export. - Drop unused render callback from OpenElement's HydrationScope. - Normalize import extension in hydrate.ts (.ts -> .js). * fix(hydration): fmt/lint/arch and consumer-local alias for HydrationScope * style: format hydration-scope.test and open-element-render for fmt:check * ci: trigger rebuild after format fixes --------- Co-authored-by: DevBot <devbot@openelement.dev> * [v0.41.0-alpha.2] Candidate 1: Split renderer from activation layer (#77) - jsx-render-dom.ts now emits BindingDescriptors and commits them via commitBindings() - Move Show/For effect lifecycle into binding-activation.ts as conditional/list bindings - Add commitBindings export to core/csr/hydrate entry points Co-authored-by: DevBot <devbot@openelement.dev> * [v0.41.0-alpha.2] Candidate 2: BindingDescriptor registry (#78) - Add factory constructors for all descriptor kinds in binding-descriptor.ts - Replace central switch in applyBindingDescriptor with internal Map registry - Add registerBindingKind for custom binding kinds - Update jsx-render-dom.ts, hydration-scope.ts, event-hydration.ts to use factories - Re-export factories and registerBindingKind from core/csr/hydrate entry points - Add custom binding kind test Co-authored-by: DevBot <devbot@openelement.dev> * docs: mark v0.41.0-alpha.2 workstreams complete * fix(core,ui): polish HydrationScope and fix token typo (closes #89) - Cache cacheAccess getter in private field to fix object identity - Remove dead VNodeCacheAccess.get() method - Mark VNodeCacheAccess and cacheAccess as @internal - Normalize import extensions to .js in hydration-scope.ts - Fix --blue-10 -> --teal-10 typo in dark-mode token block Co-authored-by: DevBot <devbot@openelement.dev> * fix(core): binding layer cleanup - factories, registry, types (closes #90) * fix(core): binding layer cleanup - factories, registry, types (#90) - Remove _root dead param from commitBindings - Add bindHtml factory for signal-html descriptors - Add overwrite warning to registerBindingKind - Remove dead keyFn field from ListBindingDescriptor - Narrow condition type to Signal<boolean> | boolean - Narrow items type to Signal<unknown[]> | unknown[] - Use bindHtml factory in collectPropBindings - Re-export bindHtml from core/csr/hydrate entry points * docs: add comments documenting narrowed type casts * fix(core): revert narrowed factory types per bot review Widen bindConditional/bindList factory signatures back to Signal<unknown> | unknown to match runtime coercion in applyConditional/applyList --------- Co-authored-by: DevBot <devbot@openelement.dev> * chore: bump versions to 0.41.0-alpha.2 and update docs (#82) * chore: bump versions to 0.41.0-alpha.2 and update roadmap (#82) - Bump all 11 packages from 0.41.0-alpha.1 to 0.41.0-alpha.2 - Mark v0.41.0-alpha.2 as Shipped in ROADMAP.md - Add completion note * fix: update PACKAGE_VERSION and docs for alpha.2 (#82) - Bump PACKAGE_VERSION in tools/project-constants.ts to 0.41.0-alpha.2 - Update README.md, README.zh.md, PROJECT_WORKFLOW.md with alpha.2 * fix: update ACTIVE_VERSION and www route version refs for alpha.2 * fix: update getting-started.tsx with alpha.2 version ref --------- Co-authored-by: DevBot <devbot@openelement.dev> * docs: fix stale version refs found by bot review of #94 * docs: fix stale version refs in ROADMAP header, README Current Line, PACKAGE_SURFACE, design README * docs: fix remaining stale version refs and PACKAGE_SURFACE protocol row - Update OPENELEMENT_VERSION constant to v0.41.0-alpha.2 - Fix hardcoded alpha.1 strings in architecture, apilist, examples routes - Add @openelement/protocol to PACKAGE_SURFACE table (11-package) * docs: fix two more stale v0.41.0-alpha.1 refs * docs: fix 14-to-10 -> 14-to-11 in PACKAGE_SURFACE.md --------- Co-authored-by: DevBot <devbot@openelement.dev> * fix: resolve bot review findings from PR #96 (dev→main) - Remove dead _hydrateSignals() method and unused hydrateSignals import - Fix inconsistent DOM clearing: shadow root now clears before null check - Import eventTypeFromProp from event-marker.js instead of event-hydration.js - Remove dead 'key' field from StaticAttrBindingDescriptor interface and factory - Remove dangling comment in protocol/manifest.ts - Update stale comments referencing _hydrateSignals Co-authored-by: DevBot <devbot@openelement.dev> * fix: address all 10 PR #99 bot review findings 1. CSR className/class props use bindAttr (signal-attr) instead of bindClass 2. collectHydrationBindings accepts lifecycle param directly 3. Make VNodeCacheAccess non-exported (file-private) 4. Add HydrationScope.createLifecycle() method 5. Remove duplicate bindHydrateEvents re-export from hydrate.ts 6. Restore framework.js barrel in protocol/src/index.ts 7. Document AbortSignal absence in open-element-render.ts 8. Make SignalRenderBindingDescriptor.lifecycle optional 9. Reject null bytes in resolveDynamicRoutePath 10. Replace ponytail comment with normal comment * Potential fix for pull request finding 'Use of returnless function' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Zhi <freemanzheng@hotmail.com> * Potential fix for pull request finding 'Use of returnless function' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Zhi <freemanzheng@hotmail.com> * Potential fix for pull request finding 'Use of returnless function' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Zhi <freemanzheng@hotmail.com> * fix: collapse dead if/else, remove unused getters, add signal-class doc - Collapse identical if/else branches in collectPropBindings - Remove unused _effectDisposers / _eventCleanups getters - Document SignalClassBindingDescriptor as DSD-only * fix: reset() ungated, registerDispose exclusive, DANGEROUS_KEYS export, constructor init - reset() no longer gates on #active so reconnection can re-hydrate - registerDispose uses AbortSignal OR disposers Set, not both (avoid double-dispose) - Drop @internal from DANGEROUS_KEYS barrel export - Move HydrationScope construction into OpenElement constructor with super() call * fix: replace cacheAccess with setCachedVNode, make hydrateSignals private, hoist inline import - Replace cacheAccess getter + VNodeCacheAccess interface with setCachedVNode method - Remove export from hydrateSignals (only used in same module) - Hoist Signal import type in open-element-render.ts to top level - Make bindRender lifecycle parameter required (no default {}) * fix: reset() reactivates scope after dispose, doc test mock leak - reset() now sets #active = true so disconnect/reconnect can re-hydrate - Add comment documenting test mock ordering requirement * fix(test): wrap mock document in per-test setup/teardown to prevent cross-file leaks * fix: add @internal annotation to DANGEROUS_KEYS barrel export * fix: remove DANGEROUS_KEYS from barrel, add ShadowRoot stub restore * fix(release): accept semver pre-release suffix in parseSemver * fix: add @internal to DANGEROUS_KEYS in static.ts, fix greedy regex * fix(release): use --allow-dirty for deno pack in release mode deno fmt may touch files outside the staged bump list, making the worktree dirty. This is safe in CI where changes are expected. * fix(release): skip already-published packages on E403 * docs: add architecture review candidates to alpha.3 plan (#107-#109) * docs: reorganize alpha.4/5 — Preact island proof to alpha.4, Deno Desktop only in alpha.5 * feat(alpha3): add web components artifact gates * refactor(alpha.3): extract smoke fixtures to files, share alias logic - Move inline fixture strings to standalone files under tools/third-party-wc-smoke/app/ - Add allPackageAliases() to tools/lib/package-graph.ts - Use allPackageAliases() in both third-party-wc-smoke.ts and consumer-local.ts - Reduces smoke test from 551 → 253 lines (54% reduction) * feat(alpha.3): complete architecture candidates #107-#109 - #107: Create @openelement/app/vite as canonical Vite entry - #108: Deepen BuildContext with recordPhase* and registerPlugin methods - #109: Consolidate test DOM harness into test-utils.ts (-619 lines) - Update alpha.3 plan checkboxes to mark all workstreams complete * fix(alpha.3): address PR #110 bot review findings - Remove inverted phase ordering check in markComplete - Fix stripComments URL mangling in check-package-artifacts - Replace module-level document mutation with setupMockDocument() - Remove unused recordPhase*Fact wrappers - Tighten registerPlugin generic type - Replace fragile path slicing with dirname() * fix(test): wrap jsx-render-dom tests in withMockDocument for test isolation * fix(alpha.3): remove app/vite re-export to break dependency cycle app→adapter-vite→app creates a cycle that breaks graph:check. Keep adapter-vite as the canonical Vite entry; update docs accordingly. * fix(alpha.3): clear remaining bot review issues - Document stripComments edge case as extremely unlikely - Remove empty onListen callback in smoke test - Move helper functions before control flow in consumer-local.ts * docs: clarify ssrNoExternal RegExp serialization contract * docs: note hardcoded version anchors in release.ts as ponytail debt * fix(alpha.3): tighten registerPlugin protocol type, doc querySelectorAll limitation * fix(alpha.3): move helpers to top of consumer-local, revert protocol registerPlugin to unknown * fix: update arch:check allowlist for sitemap registerPlugin * fix(release): update version anchors from 0.40.8 to 0.41.0-alpha.2 * docs: mark alpha.3 as Shipped, update alpha.5 to Deno Desktop * feat(alpha.4): add hydrateOpenElement client runtime to core/hydrate * feat(alpha.4): add Fresh example with openElement + Preact island * feat(alpha.4): complete remaining tasks - smoke test, docs, plan update - Preact island smoke test (18 tests covering SSR, props, signals, lifecycle) - Fresh integration docs (docs/integrations/open-element-in-fresh.md) - Alpha.4 plan checkboxes updated (15 items marked complete) - Fresh example now uses hydrateOpenElement from core/hydrate * fix(alpha.4): use real hydrateOpenElement, format Fresh files * fix alpha4 ci review issues * fix alpha4 review followups * fix alpha4 final review gaps * fix alpha4 review docs and preact proof * fix alpha4 test stub cleanup * docs: mark alpha.4 release workflow items as done --------- Signed-off-by: Zhi <freemanzheng@hotmail.com> Co-authored-by: DevBot <devbot@openelement.dev> Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>










v0.41.0-alpha.3 — Cross-Framework Web Components Integration
Mature WC Library Direct Use
Pure ESM / ECMAScript Quality Gates
Architecture Deepening
Fixes & Refactoring
Closes #107, #108, #109.