Skip to content

chore: version packages - #163

Merged
jamiedavenport merged 1 commit into
mainfrom
changeset-release/main
Jul 27, 2026
Merged

chore: version packages#163
jamiedavenport merged 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@policystack/angular@1.2.0

Minor Changes

  • 279688a: Consent preference toggles are now staged. toggle() writes to state.draft instead of live decisions, and nothing is gated, persisted, or script-loaded until save() promotes the draft in one step — scripts no longer load on checkbox tick before "Save", and returning visitors no longer get their stored record rewritten on every tick (Consent store: preferences toggles mutate live state before Save (scripts load on checkbox tick) #157). Leaving the preferences route without saving discards the draft.

    API changes: toggle(key) no longer accepts ActionOptions (name the record source at save() instead), and ConsentState gains a required draft field. Per-category granted accessors in all framework bindings read draft ?? decisions so checkboxes respond instantly; custom panels rendering checkboxes from raw decisions should apply the same merge.

@policystack/core@1.2.0

Minor Changes

  • 4cc5985: cookieAdapter() now exposes the bare cookie value, so nothing has to re-implement its wire format (cookieAdapter: no way to get the encoded cookie value (forces hand-rolled base64url in tests) #167). encode/decode already existed as private closures; the adapter just never returned them, leaving getSetCookieHeader() (a whole Set-Cookie header) as the closest thing and forcing consumers to hand-roll base64url or string-parse the value back out.

    Three new members on CookieAdapter:

    • serialize(record) — the encoded cookie value on its own, exactly what write() puts in the cookie.
    • deserialize(value) — the inverse, for a bare value. parse() still handles a full cookie header.
    • name — the resolved cookie name, so callers using the default do not hardcode oc_consent.

    The motivating case is seeding consent in browser tests, where browserContext.addCookies() needs a name and a value:

    const adapter = cookieAdapter();
    const store = createConsentStore(policystack);
    store.acceptAll();
    
    await context.addCookies([
      {
        name: adapter.name,
        value: adapter.serialize(store.getConsentRecord()),
        url: baseURL,
      },
    ]);

    A copied encoder is worth replacing here even though it matches today: deserialize swallows errors and returns null, so a value that drifts from the adapter's format does not throw — consent silently reads as undecided and the banner reappears.

  • e0fc26a: Consent hooks no longer cause hydration mismatches under SSR. The React hooks passed live store state as useSyncExternalStore's getServerSnapshot, so any returning visitor mismatched: the server has no stored record and resolves the host's timezone, while the client has both (SSR: getServerSnapshot returns live store state — guaranteed hydration mismatch for returning visitors #158). Every SSR consumer had to hand-roll a mounted flag around consent-driven UI.

    ConsentStore gains a server member (getState() / has()) returning a deterministic pre-consent snapshot: undecided, no jurisdiction, conservative opt-in posture, derived from static config alone and never from the adapter or resolver. useConsent, useCategory, and ConsentGate pass it as getServerSnapshot, and React re-reads live state once hydration commits.

    The Vue, Svelte, Solid, and Angular bindings still seed from live state and are unchanged here; store.server is the shared primitive their fix will use.

  • 279688a: Consent preference toggles are now staged. toggle() writes to state.draft instead of live decisions, and nothing is gated, persisted, or script-loaded until save() promotes the draft in one step — scripts no longer load on checkbox tick before "Save", and returning visitors no longer get their stored record rewritten on every tick (Consent store: preferences toggles mutate live state before Save (scripts load on checkbox tick) #157). Leaving the preferences route without saving discards the draft.

    API changes: toggle(key) no longer accepts ActionOptions (name the record source at save() instead), and ConsentState gains a required draft field. Per-category granted accessors in all framework bindings read draft ?? decisions so checkboxes respond instantly; custom panels rendering checkboxes from raw decisions should apply the same merge.

@policystack/react@1.2.0

Minor Changes

  • 996973e: @policystack/react/consent now exposes the provider's consent store, so gateScript and the @policystack/scripts catalogue are usable with the React bindings (No way to reach the provider's ConsentStore — gateScript unusable with framework bindings #159). Previously <PolicyStack> created its store privately and nothing exported it, leaving no way to obtain the ConsentStore that gateScript(store, def) requires.

    Two new exports:

    • <GatedScript def={...} /> — the React binding for gateScript. Takes the store from <PolicyStack>, gates the script for as long as it is mounted, and disposes on unmount. Renders no DOM and is inert during SSR. Building the definition inline (def={ga4({ measurementId: "G-XXXXXXX" })}) is safe: the gate follows def.id, so a fresh object each render neither re-gates nor drops queued pre-consent calls. Optional onEvent receives the ScriptEvent stream.
    • useConsentStore() — returns the ConsentStore for handing to other core free functions such as gateScripts. Stable for the life of the provider and non-reactive; keep using useConsent / useCategory / <ConsentGate> to react to state.

    Both throw the existing provider guard outside <PolicyStack> or under a policy-only config. That error message now names the full consent API rather than three of its members.

  • e0fc26a: Consent hooks no longer cause hydration mismatches under SSR. The React hooks passed live store state as useSyncExternalStore's getServerSnapshot, so any returning visitor mismatched: the server has no stored record and resolves the host's timezone, while the client has both (SSR: getServerSnapshot returns live store state — guaranteed hydration mismatch for returning visitors #158). Every SSR consumer had to hand-roll a mounted flag around consent-driven UI.

    ConsentStore gains a server member (getState() / has()) returning a deterministic pre-consent snapshot: undecided, no jurisdiction, conservative opt-in posture, derived from static config alone and never from the adapter or resolver. useConsent, useCategory, and ConsentGate pass it as getServerSnapshot, and React re-reads live state once hydration commits.

    The Vue, Svelte, Solid, and Angular bindings still seed from live state and are unchanged here; store.server is the shared primitive their fix will use.

  • 279688a: Consent preference toggles are now staged. toggle() writes to state.draft instead of live decisions, and nothing is gated, persisted, or script-loaded until save() promotes the draft in one step — scripts no longer load on checkbox tick before "Save", and returning visitors no longer get their stored record rewritten on every tick (Consent store: preferences toggles mutate live state before Save (scripts load on checkbox tick) #157). Leaving the preferences route without saving discards the draft.

    API changes: toggle(key) no longer accepts ActionOptions (name the record source at save() instead), and ConsentState gains a required draft field. Per-category granted accessors in all framework bindings read draft ?? decisions so checkboxes respond instantly; custom panels rendering checkboxes from raw decisions should apply the same merge.

@policystack/solid@1.2.0

Minor Changes

  • 279688a: Consent preference toggles are now staged. toggle() writes to state.draft instead of live decisions, and nothing is gated, persisted, or script-loaded until save() promotes the draft in one step — scripts no longer load on checkbox tick before "Save", and returning visitors no longer get their stored record rewritten on every tick (Consent store: preferences toggles mutate live state before Save (scripts load on checkbox tick) #157). Leaving the preferences route without saving discards the draft.

    API changes: toggle(key) no longer accepts ActionOptions (name the record source at save() instead), and ConsentState gains a required draft field. Per-category granted accessors in all framework bindings read draft ?? decisions so checkboxes respond instantly; custom panels rendering checkboxes from raw decisions should apply the same merge.

@policystack/svelte@1.2.0

Minor Changes

  • 279688a: Consent preference toggles are now staged. toggle() writes to state.draft instead of live decisions, and nothing is gated, persisted, or script-loaded until save() promotes the draft in one step — scripts no longer load on checkbox tick before "Save", and returning visitors no longer get their stored record rewritten on every tick (Consent store: preferences toggles mutate live state before Save (scripts load on checkbox tick) #157). Leaving the preferences route without saving discards the draft.

    API changes: toggle(key) no longer accepts ActionOptions (name the record source at save() instead), and ConsentState gains a required draft field. Per-category granted accessors in all framework bindings read draft ?? decisions so checkboxes respond instantly; custom panels rendering checkboxes from raw decisions should apply the same merge.

@policystack/vue@1.2.0

Minor Changes

  • 279688a: Consent preference toggles are now staged. toggle() writes to state.draft instead of live decisions, and nothing is gated, persisted, or script-loaded until save() promotes the draft in one step — scripts no longer load on checkbox tick before "Save", and returning visitors no longer get their stored record rewritten on every tick (Consent store: preferences toggles mutate live state before Save (scripts load on checkbox tick) #157). Leaving the preferences route without saving discards the draft.

    API changes: toggle(key) no longer accepts ActionOptions (name the record source at save() instead), and ConsentState gains a required draft field. Per-category granted accessors in all framework bindings read draft ?? decisions so checkboxes respond instantly; custom panels rendering checkboxes from raw decisions should apply the same merge.

@policystack/cli@1.2.0

Patch Changes

  • Updated dependencies [035afc7]
    • @policystack/vite@1.2.0

@policystack/renderers@1.2.0

Patch Changes

  • Updated dependencies [4cc5985]
  • Updated dependencies [e0fc26a]
  • Updated dependencies [279688a]
    • @policystack/core@1.2.0

@policystack/vite@1.2.0

Patch Changes

  • 035afc7: policystack.gen.ts is no longer rewritten on every build, so it stops fighting the consumer's formatter (vite: policystack.gen.ts rewritten unformatted on every build, fights consumer formatters #166).

    The file is meant to be committed, which puts it under whatever formatter the project runs — and the plugin's raw JSON.stringify output was never going to match. Since the plugin rewrote it unconditionally at buildStart, every build undid the formatting and left a spurious diff, a red format check, and a build → reformat → build loop that never settled.

    The header now carries a digest of the scanned content:

    // AUTO-GENERATED by @policystack/vite — do not edit. (scan: 66861eea20c06b94)

    Each build compares that digest against the current scan and skips the write entirely when they match, whatever the file has been reformatted to since — a // comment survives every formatter. The digest covers only what the module renders, so it is insensitive to scan ordering (renaming a source file no longer counts as a change) and to scanner diagnostics. A missing or unreadable header rewrites, so a hand-edited or pre-digest file self-heals.

    The output is also pretty-printed now — one entry per line, trailing commas, {} for empty interface bodies, quotes on augmentation keys only where an identifier will not do — which narrows the diff on the builds where a rewrite is genuinely needed. Values stay fully quoted so each literal remains parseable as JSON.

    Existing policystack.gen.ts files have no digest and will be rewritten once, on the first build after upgrading.

  • Updated dependencies [4cc5985]

  • Updated dependencies [e0fc26a]

  • Updated dependencies [279688a]

    • @policystack/core@1.2.0

@policystack/scripts@1.2.0

@policystack/sdk@1.2.0

astro-example@0.0.1

Patch Changes

  • Updated dependencies [996973e]
  • Updated dependencies [e0fc26a]
  • Updated dependencies [279688a]
    • @policystack/react@1.2.0

@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
op-demo Ready Ready Preview, Comment Jul 27, 2026 3:52pm
openpolicy-sh Ready Ready Preview, Comment Jul 27, 2026 3:52pm
policystack Ready Ready Preview, Comment Jul 27, 2026 3:52pm

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant