@inox-tools/request-state 0.8.1 → 1.0.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.
@@ -1,2 +1,2 @@
1
- import {AsyncLocalStorage}from'node:async_hooks';import {stringify}from'devalue';const o=new AsyncLocalStorage,l=(t,e)=>{const n=o.getStore();if(n!==void 0)return n.has(t)||e!==void 0&&n.set(t,e),n.get(t)},p=t=>o.getStore()?.has(t)||false,S=(t,e)=>{o.getStore()?.set(t,e);},i=new Map(Object.entries(Symbol).filter(([t,e])=>typeof e=="symbol"&&typeof t=="string").map(([t,e])=>[e,t])),a={undefined:t=>t===void 0,URL:t=>t instanceof URL&&t.href,Date:t=>t instanceof Date&&t.valueOf(),GlobalSymbol:t=>typeof t=="symbol"&&t.description!==void 0&&t===Symbol.for(t.description)&&t.description,WellKnownSymbol:t=>typeof t=="symbol"&&i.get(t)},d=async t=>{const e=new Map;return {result:await o.run(e,t),getState:()=>e.size>0&&stringify(e,a)}};export{d as collectState,l as getState,p as hasState,S as setState};//# sourceMappingURL=serverState.js.map
1
+ export{d as collectState,a as getState,b as hasState,c as setState}from'../chunk-GHTUQIMX.js';//# sourceMappingURL=serverState.js.map
2
2
  //# sourceMappingURL=serverState.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/serverState.ts"],"names":["store","AsyncLocalStorage","getState","key","valueIfMissing","state","hasState","setState","value","wellKnownSymbols","reducers","collectState","cb","stringify"],"mappings":"iFAKA,MAAMA,CAAAA,CAAQ,IAAIC,kBAELC,CAAAA,CAAW,CAACC,EAAaC,CAAAA,GAAsC,CAC3E,MAAMC,CAAAA,CAAQL,CAAAA,CAAM,QAAA,EAAS,CAC7B,GAAIK,CAAAA,GAAU,MAAA,CAEd,OAAKA,CAAAA,CAAM,IAAIF,CAAG,CAAA,EACbC,CAAAA,GAAmB,MAAA,EACtBC,EAAM,GAAA,CAAIF,CAAAA,CAAKC,CAAc,CAAA,CAGxBC,CAAAA,CAAM,IAAIF,CAAG,CACrB,CAAA,CAEaG,CAAAA,CAAYH,GAAgBH,CAAAA,CAAM,QAAA,EAAS,EAAG,GAAA,CAAIG,CAAG,CAAA,EAAK,KAAA,CAE1DI,CAAAA,CAAW,CAACJ,EAAaK,CAAAA,GAAyB,CAChDR,EAAM,QAAA,EAAS,EACtB,IAAIG,CAAAA,CAAKK,CAAK,EACtB,CAAA,CAOMC,EAAmB,IAAI,GAAA,CAC5B,OAAO,OAAA,CAAQ,MAAM,EACnB,MAAA,CAAO,CAAC,CAACN,CAAAA,CAAKK,CAAK,CAAA,GAAM,OAAOA,GAAU,QAAA,EAAY,OAAOL,GAAQ,QAAQ,CAAA,CAC7E,GAAA,CAAI,CAAC,CAACA,CAAAA,CAAKK,CAAK,CAAA,GAAM,CAACA,EAAOL,CAAG,CAAC,CACrC,CAAA,CAEMO,EAAgD,CACrD,SAAA,CAAYF,GAAUA,CAAAA,GAAU,MAAA,CAChC,IAAMA,CAAAA,EAAUA,CAAAA,YAAiB,GAAA,EAAOA,CAAAA,CAAM,KAC9C,IAAA,CAAOA,CAAAA,EAAUA,CAAAA,YAAiB,IAAA,EAAQA,EAAM,OAAA,EAAQ,CACxD,YAAA,CAAeA,CAAAA,EACd,OAAOA,CAAAA,EAAU,QAAA,EACjBA,EAAM,WAAA,GAAgB,MAAA,EACtBA,IAAU,MAAA,CAAO,GAAA,CAAIA,CAAAA,CAAM,WAAW,GACtCA,CAAAA,CAAM,WAAA,CACP,eAAA,CAAkBA,CAAAA,EAAU,OAAOA,CAAAA,EAAU,QAAA,EAAYC,CAAAA,CAAiB,GAAA,CAAID,CAAK,CACpF,CAAA,CAEaG,EAAe,MAAUC,CAAAA,EAAqD,CAC1F,MAAMP,CAAAA,CAAQ,IAAI,GAAA,CAElB,OAAO,CACN,MAAA,CAFc,MAAML,CAAAA,CAAM,GAAA,CAAIK,EAAOO,CAAE,CAAA,CAGvC,QAAA,CAAU,IAAMP,EAAM,IAAA,CAAO,CAAA,EAAKQ,UAAUR,CAAAA,CAAOK,CAAQ,CAC5D,CACD","file":"serverState.js","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport { stringify } from 'devalue';\n\ntype State = Map<string, unknown>;\n\nconst store = new AsyncLocalStorage<State>();\n\nexport const getState = (key: string, valueIfMissing?: unknown): unknown => {\n\tconst state = store.getStore();\n\tif (state === undefined) return;\n\n\tif (!state.has(key)) {\n\t\tif (valueIfMissing !== undefined) {\n\t\t\tstate.set(key, valueIfMissing);\n\t\t}\n\t}\n\treturn state.get(key);\n};\n\nexport const hasState = (key: string) => store.getStore()?.has(key) || false;\n\nexport const setState = (key: string, value: unknown): void => {\n\tconst state = store.getStore();\n\tstate?.set(key, value);\n};\n\nexport type CollectedState<T> = {\n\tgetState: () => string | false;\n\tresult: T;\n};\n\nconst wellKnownSymbols = new Map(\n\tObject.entries(Symbol)\n\t\t.filter(([key, value]) => typeof value === 'symbol' && typeof key === 'string')\n\t\t.map(([key, value]) => [value, key])\n);\n\nconst reducers: Record<string, (value: any) => any> = {\n\tundefined: (value) => value === undefined,\n\tURL: (value) => value instanceof URL && value.href,\n\tDate: (value) => value instanceof Date && value.valueOf(),\n\tGlobalSymbol: (value) =>\n\t\ttypeof value === 'symbol' &&\n\t\tvalue.description !== undefined &&\n\t\tvalue === Symbol.for(value.description) &&\n\t\tvalue.description,\n\tWellKnownSymbol: (value) => typeof value === 'symbol' && wellKnownSymbols.get(value),\n};\n\nexport const collectState = async <R>(cb: () => Promise<R>): Promise<CollectedState<R>> => {\n\tconst state = new Map();\n\tconst result = await store.run(state, cb);\n\treturn {\n\t\tresult,\n\t\tgetState: () => state.size > 0 && stringify(state, reducers),\n\t};\n};\n"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"serverState.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inox-tools/request-state",
3
- "version": "0.8.1",
3
+ "version": "1.0.0",
4
4
  "description": "Shared request state between server and client",
5
5
  "keywords": [
6
6
  "astro-integration",
@@ -26,24 +26,24 @@
26
26
  "virtual.d.ts"
27
27
  ],
28
28
  "dependencies": {
29
- "astro-integration-kit": "~0.19.1",
30
- "content-type": "^1.0.5",
31
- "devalue": "^5.6.2",
32
- "@inox-tools/utils": "^1.0.0"
29
+ "astro-integration-kit": "~0.20.0",
30
+ "devalue": "^5.6.3",
31
+ "@inox-tools/utils": "^1.1.1"
33
32
  },
34
33
  "devDependencies": {
35
34
  "@playwright/test": "^1.58.2",
36
35
  "@types/content-type": "^1.1.9",
37
- "@types/node": "^25.2.2",
38
- "astro": "^5.17.1",
36
+ "@types/node": "^25.3.3",
37
+ "astro": "^6.0.8",
38
+ "content-type": "^1.0.5",
39
39
  "jest-extended": "^7.0.0",
40
40
  "tsup": "8.5.1",
41
41
  "typescript": "^5.9.3",
42
42
  "vite": "^7.3.1",
43
- "@inox-tools/astro-tests": "^0.9.1"
43
+ "@inox-tools/astro-tests": "^1.0.0"
44
44
  },
45
45
  "peerDependencies": {
46
- "astro": "^5"
46
+ "astro": "^6"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "tsup",
@@ -2,6 +2,8 @@ import { defineMiddleware } from 'astro/middleware';
2
2
  import { collectState } from './serverState.js';
3
3
  import { parse } from 'content-type';
4
4
 
5
+ const encoder = new TextEncoder();
6
+
5
7
  export const onRequest = defineMiddleware(async (_, next) => {
6
8
  const { getState, result } = await collectState(next);
7
9
 
@@ -19,17 +21,27 @@ export const onRequest = defineMiddleware(async (_, next) => {
19
21
  const stateScript = state
20
22
  ? `<script class="it-astro-state" type="application/json+devalue">${state}</script>`
21
23
  : null;
22
- if (stateScript) {
23
- const headCloseIndex = originalBody.indexOf('</head>');
24
- if (headCloseIndex > -1) {
25
- return new Response(
26
- originalBody.slice(0, headCloseIndex) + stateScript + originalBody.slice(headCloseIndex),
27
- result
28
- );
29
- } else {
30
- return new Response(stateScript + originalBody, result);
31
- }
24
+
25
+ if (!stateScript) {
26
+ return new Response(originalBody, result);
32
27
  }
33
28
 
34
- return new Response(originalBody, result);
29
+ const headCloseIndex = originalBody.indexOf('</head>');
30
+ const finalBody =
31
+ headCloseIndex > -1
32
+ ? originalBody.slice(0, headCloseIndex) + stateScript + originalBody.slice(headCloseIndex)
33
+ : stateScript + originalBody;
34
+
35
+ // TextEncoder is also supported in CloudFlare Workers, so this should work in all environments Astro supports.
36
+ const encodedBody = encoder.encode(finalBody);
37
+ const contentLength = encodedBody.byteLength;
38
+
39
+ const headers = new Headers(result.headers);
40
+ headers.set('Content-Length', contentLength.toString());
41
+
42
+ return new Response(encodedBody, {
43
+ status: result.status,
44
+ statusText: result.statusText,
45
+ headers,
46
+ });
35
47
  });