@c9up/aurora 0.1.32 → 0.1.33

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.
@@ -30,19 +30,23 @@ const renderScope = new AsyncLocalStorage();
30
30
  setCookieStoreReader(() => renderScope.getStore()?.cookies);
31
31
  setRouteManifestReader(() => renderScope.getStore()?.routes);
32
32
  function isCookieReadable(request) {
33
- return (typeof request === "object" &&
34
- request !== null &&
35
- "cookie" in request &&
36
- typeof request.cookie === "function");
33
+ if (typeof request !== "object" || request === null)
34
+ return false;
35
+ return (typeof Reflect.get(request, "plainCookie") === "function" ||
36
+ typeof Reflect.get(request, "cookie") === "function");
37
37
  }
38
38
  /** Read the allowlisted cookies off the request into a `name → value` seed. */
39
39
  function readRequestCookies(request, names) {
40
40
  if (!isCookieReadable(request))
41
41
  return {};
42
42
  const seed = {};
43
+ // Unsigned first; `cookie()` only when the host offers nothing else.
44
+ const read = request.plainCookie
45
+ ? (name) => request.plainCookie?.(name, undefined, { encoded: false })
46
+ : (name) => request.cookie?.(name);
43
47
  for (const name of names) {
44
- const value = request.cookie(name);
45
- if (value !== null)
48
+ const value = read(name);
49
+ if (value !== null && value !== undefined)
46
50
  seed[name] = value;
47
51
  }
48
52
  return seed;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/aurora",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
4
4
  "description": "Aurora — reactive UI runtime for the Ream framework. Tagged-template DOM, signal-based state, isomorphic SSR + hydration, zero build step.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -142,8 +142,24 @@ export type SharedPropsResolver = (
142
142
  ) => SharedProps | Promise<SharedProps>;
143
143
 
144
144
  /** A request that can read a cookie by name — the structural slice we need. */
145
+ /**
146
+ * The slice of a host request this needs: reading a cookie the browser wrote.
147
+ *
148
+ * `plainCookie` is the one to use. These cookies are written client-side
149
+ * through `document.cookie`, so they carry no signature; a host whose
150
+ * `cookie()` verifies one (as Ream's does) returns nothing for them, and the
151
+ * seed silently empties — which is the flash this exists to prevent.
152
+ *
153
+ * `cookie` is accepted as a fallback so a host that only offers that spelling
154
+ * still seeds, rather than rendering default state and saying nothing.
155
+ */
145
156
  interface CookieReadableRequest {
146
- cookie(name: string): string | null;
157
+ plainCookie?<T = string>(
158
+ name: string,
159
+ defaultValue?: T,
160
+ options?: { encoded?: boolean },
161
+ ): T | null;
162
+ cookie?(name: string): string | null;
147
163
  }
148
164
 
149
165
  interface RenderScope {
@@ -157,11 +173,10 @@ setCookieStoreReader(() => renderScope.getStore()?.cookies);
157
173
  setRouteManifestReader(() => renderScope.getStore()?.routes);
158
174
 
159
175
  function isCookieReadable(request: unknown): request is CookieReadableRequest {
176
+ if (typeof request !== "object" || request === null) return false;
160
177
  return (
161
- typeof request === "object" &&
162
- request !== null &&
163
- "cookie" in request &&
164
- typeof request.cookie === "function"
178
+ typeof Reflect.get(request, "plainCookie") === "function" ||
179
+ typeof Reflect.get(request, "cookie") === "function"
165
180
  );
166
181
  }
167
182
 
@@ -172,9 +187,14 @@ function readRequestCookies(
172
187
  ): Record<string, string> {
173
188
  if (!isCookieReadable(request)) return {};
174
189
  const seed: Record<string, string> = {};
190
+ // Unsigned first; `cookie()` only when the host offers nothing else.
191
+ const read = request.plainCookie
192
+ ? (name: string) =>
193
+ request.plainCookie?.<string>(name, undefined, { encoded: false })
194
+ : (name: string) => request.cookie?.(name);
175
195
  for (const name of names) {
176
- const value = request.cookie(name);
177
- if (value !== null) seed[name] = value;
196
+ const value = read(name);
197
+ if (value !== null && value !== undefined) seed[name] = value;
178
198
  }
179
199
  return seed;
180
200
  }