@mhmo91/schmancy 0.10.10 → 0.10.12
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.
- package/dist/agent/schmancy.agent.js.map +1 -1
- package/dist/handover/agent-runtime-followups.md +1 -1
- package/dist/handover/agent-runtime-v1.md +3 -3
- package/dist/handover/claude-design-brief.md +86 -46
- package/dist/handover/claude-design-setup.md +11 -7
- package/dist/handover/schmancy-token-reference.md +12 -6
- package/dist/skills/INDEX.md +1 -1
- package/dist/skills/SKILL.md +7 -6
- package/dist/skills/audio.md +1 -1
- package/dist/skills/discovery.md +3 -3
- package/dist/skills/menu.md +1 -1
- package/dist/skills/overlay.md +1 -1
- package/dist/skills/schmancy/INDEX.md +1 -1
- package/dist/skills/schmancy/SKILL.md +7 -6
- package/dist/skills/schmancy/audio.md +1 -1
- package/dist/skills/schmancy/discovery.md +3 -3
- package/dist/skills/schmancy/menu.md +1 -1
- package/dist/skills/schmancy/overlay.md +1 -1
- package/dist/skills/schmancy/state.md +42 -22
- package/dist/skills/state.md +42 -22
- package/dist/state-BusMG6sM.js.map +1 -1
- package/dist/state-DNdCPITt.cjs.map +1 -1
- package/package.json +1 -1
- package/skills/schmancy/INDEX.md +1 -1
- package/skills/schmancy/SKILL.md +7 -6
- package/skills/schmancy/audio.md +1 -1
- package/skills/schmancy/discovery.md +3 -3
- package/skills/schmancy/menu.md +1 -1
- package/skills/schmancy/overlay.md +1 -1
- package/skills/schmancy/state.md +42 -22
- package/src/CLAUDE.md +112 -354
- package/src/state/CLAUDE.md +26 -18
- package/src/state/SCOPING.md +23 -9
package/src/state/SCOPING.md
CHANGED
|
@@ -14,7 +14,7 @@ import { state } from '@mhmo91/schmancy/state'
|
|
|
14
14
|
|
|
15
15
|
const cart = state<CartState>('hannah/cart').session({ items: [], total: 0 })
|
|
16
16
|
|
|
17
|
-
class App extends
|
|
17
|
+
class App extends SchmancyElement {
|
|
18
18
|
render() {
|
|
19
19
|
return html`
|
|
20
20
|
<schmancy-context .provides=${[cart]}>
|
|
@@ -53,11 +53,21 @@ component naturally writes. It handles:
|
|
|
53
53
|
| Class methods called from event handlers (sync) | Same prototype-wrap. |
|
|
54
54
|
| `await` continuations inside class methods | A `Promise.prototype.then` patch in `state/active-host.ts` propagates the host across each `.then` boundary. |
|
|
55
55
|
| `addEventListener(type, fn)` on the host | Wrapped at the `SchmancyElement` layer; `removeEventListener` re-finds the wrapped listener via a `WeakMap`. |
|
|
56
|
-
| Inline arrow handlers attached via Lit templates (`@click=${() => …}`) |
|
|
56
|
+
| Inline arrow handlers attached via Lit templates (`@click=${() => …}`) and any other DOM event in a `<schmancy-context>` subtree | `<schmancy-context>` installs capture-phase listeners on itself for ~18 common event types and calls `_publishEventHost(target)` from each — `resolveActiveHost()` reads that slot for the duration of the synchronous handler chain. |
|
|
57
|
+
|
|
58
|
+
**Known limitation — native `await` on a native Promise.** V8's await
|
|
59
|
+
optimization (since 7.x) skips the spec-prescribed
|
|
60
|
+
`Promise.resolve(x).then(continuation)` step, so the Promise.then
|
|
61
|
+
patch does not see the resumption. Class methods that mutate state
|
|
62
|
+
across an `await` boundary fall back to the module-scoped global,
|
|
63
|
+
not the active-host's isolated copy. To preserve the host across
|
|
64
|
+
awaits, keep the mutation in the synchronous prelude before the first
|
|
65
|
+
`await`, or chain explicitly with `.then(...)` (which still routes
|
|
66
|
+
through the patched method).
|
|
57
67
|
|
|
58
68
|
Pure async callbacks with no DOM origin — a websocket `onmessage`
|
|
59
69
|
unrelated to any user gesture, a `setInterval` body running on its own
|
|
60
|
-
schedule — fall through to the module-scoped global. That is the
|
|
70
|
+
schedule — also fall through to the module-scoped global. That is the
|
|
61
71
|
correct semantic: those callbacks have no tree position to resolve to.
|
|
62
72
|
|
|
63
73
|
## Lifecycle
|
|
@@ -98,12 +108,12 @@ reference to `cart.signal` and the host later moves into a different
|
|
|
98
108
|
```ts
|
|
99
109
|
// ✗ Don't
|
|
100
110
|
const sig = cart.signal
|
|
101
|
-
class Foo extends
|
|
111
|
+
class Foo extends SchmancyElement {
|
|
102
112
|
render() { return html`${sig.get().n}` } // never re-resolves
|
|
103
113
|
}
|
|
104
114
|
|
|
105
115
|
// ✓ Do
|
|
106
|
-
class Foo extends
|
|
116
|
+
class Foo extends SchmancyElement {
|
|
107
117
|
render() { return html`${cart.value.n}` } // resolves fresh each render
|
|
108
118
|
}
|
|
109
119
|
```
|
|
@@ -118,12 +128,16 @@ and use the persistent backend on that.
|
|
|
118
128
|
## Implementation primer (for contributors)
|
|
119
129
|
|
|
120
130
|
- `state/active-host.ts` — `_activeHost` Variable (stack) +
|
|
121
|
-
one-time `Promise.prototype.then` patch +
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
131
|
+
one-time `Promise.prototype.then` patch + `_publishEventHost(node)`
|
|
132
|
+
slot + 4-tier `resolveActiveHost` fallback (stack → event-host slot
|
|
133
|
+
→ `document.activeElement` → undefined). ~190 lines. Hand-rolled
|
|
134
|
+
because no official, supported TC39 AsyncContext.Variable polyfill
|
|
135
|
+
exists today; the patch decommissions cleanly when one ships.
|
|
125
136
|
- `state/schmancy-context.ts` — the element. One `ContextProvider`
|
|
126
137
|
(`@lit/context`) per state in `provides`. Destroys on disconnect.
|
|
138
|
+
Also installs capture-phase listeners on itself for ~18 common
|
|
139
|
+
event types and publishes the event target as the active host while
|
|
140
|
+
the synchronous handler chain runs.
|
|
127
141
|
- `state/index.ts` — every read (`value` / `signal` / `$`) and every
|
|
128
142
|
write on a global instance routes through `resolveContextual`,
|
|
129
143
|
which dispatches a `context-request` event from the active host and
|