@tanstack/start-static-server-functions 1.132.0-alpha.4 → 1.132.0-alpha.7

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,8 +30,8 @@ async function addItemToCache({
30
30
  {
31
31
  const hash = jsonToFilenameSafeString(data);
32
32
  const url = await getStaticCacheUrl({ functionId, hash });
33
- const publicUrl = process.env.TSS_OUTPUT_PUBLIC_DIR;
34
- const filePath = path.join(publicUrl, url);
33
+ const clientUrl = process.env.TSS_CLIENT_OUTPUT_DIR;
34
+ const filePath = path.join(clientUrl, url);
35
35
  await fs.mkdir(path.dirname(filePath), { recursive: true });
36
36
  const stringifiedResult = JSON.stringify(
37
37
  await toJSONAsync(
@@ -1 +1 @@
1
- {"version":3,"file":"staticFunctionMiddleware.js","sources":["../../src/staticFunctionMiddleware.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport {\n createMiddleware,\n getDefaultSerovalPlugins,\n} from '@tanstack/start-client-core'\nimport { fromJSON, toJSONAsync } from 'seroval'\n\ntype StaticCachedResult = {\n result: any\n context: any\n}\n\n/**\n * This is a simple hash function for generating a hash from a string to make the filenames shorter.\n *\n * It is not cryptographically secure (as its using SHA-1) and should not be used for any security purposes.\n *\n * It is only used to generate a hash for the static cache filenames.\n *\n * @param message - The input string to hash.\n * @returns A promise that resolves to the SHA-1 hash of the input string in hexadecimal format.\n *\n * @example\n * ```typescript\n * const hash = await sha1Hash(\"hello\");\n * console.log(hash); // Outputs the SHA-1 hash of \"hello\" -> \"aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d\"\n * ```\n */\nasync function sha1Hash(message: string): Promise<string> {\n // Encode the string as UTF-8\n const msgBuffer = new TextEncoder().encode(message)\n\n // Hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-1', msgBuffer)\n\n // Convert the ArrayBuffer to a string\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')\n return hashHex\n}\n\nconst getStaticCacheUrl = async (opts: {\n functionId: string\n hash: string\n}) => {\n const filename = await sha1Hash(`${opts.functionId}__${opts.hash}`)\n return `/__tsr/staticServerFnCache/${filename}.json`\n}\n\nconst jsonToFilenameSafeString = (json: any) => {\n // Custom replacer to sort keys\n const sortedKeysReplacer = (key: string, value: any) =>\n value && typeof value === 'object' && !Array.isArray(value)\n ? Object.keys(value)\n .sort()\n .reduce((acc: any, curr: string) => {\n acc[curr] = value[curr]\n return acc\n }, {})\n : value\n\n // Convert JSON to string with sorted keys\n const jsonString = JSON.stringify(json ?? '', sortedKeysReplacer)\n\n // Replace characters invalid in filenames\n return jsonString\n .replace(/[/\\\\?%*:|\"<>]/g, '-') // Replace invalid characters with a dash\n .replace(/\\s+/g, '_') // Optionally replace whitespace with underscores\n}\n\nconst staticClientCache =\n typeof document !== 'undefined' ? new Map<string, any>() : null\n\nasync function addItemToCache({\n functionId,\n data,\n response,\n}: {\n functionId: string\n data: any\n response: StaticCachedResult\n}): Promise<void> {\n {\n const hash = jsonToFilenameSafeString(data)\n const url = await getStaticCacheUrl({ functionId, hash })\n const publicUrl = process.env.TSS_OUTPUT_PUBLIC_DIR!\n const filePath = path.join(publicUrl, url)\n\n // Ensure the directory exists\n await fs.mkdir(path.dirname(filePath), { recursive: true })\n\n // Store the result with fs\n const stringifiedResult = JSON.stringify(\n await toJSONAsync(\n {\n result: response.result,\n context: response.context.sendContext,\n },\n { plugins: getDefaultSerovalPlugins() },\n ),\n )\n await fs.writeFile(filePath, stringifiedResult, 'utf-8')\n }\n}\n\nconst fetchItem = async ({\n data,\n functionId,\n}: {\n data: any\n functionId: string\n}) => {\n const hash = jsonToFilenameSafeString(data)\n const url = await getStaticCacheUrl({ functionId, hash })\n\n let result: any = staticClientCache?.get(url)\n\n result = await fetch(url, {\n method: 'GET',\n })\n .then((r) => r.json())\n .then((d) => fromJSON(d, { plugins: getDefaultSerovalPlugins() }))\n\n return result\n}\n\nexport const staticFunctionMiddleware = createMiddleware({ type: 'function' })\n .client(async (ctx) => {\n if (\n process.env.NODE_ENV === 'production' &&\n // do not run this during SSR on the server\n typeof document !== 'undefined'\n ) {\n const response = await fetchItem({\n functionId: ctx.functionId,\n data: ctx.data,\n })\n\n if (response) {\n return {\n result: response.result,\n context: { ...(ctx as any).context, ...response.context },\n } as any\n }\n }\n return ctx.next()\n })\n .server(async (ctx) => {\n const response = await ctx.next()\n if (process.env.NODE_ENV === 'production') {\n await addItemToCache({\n functionId: ctx.functionId,\n response: { result: (response as any).result, context: ctx },\n data: ctx.data,\n })\n }\n\n return response\n })\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"staticFunctionMiddleware.js","sources":["../../src/staticFunctionMiddleware.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport {\n createMiddleware,\n getDefaultSerovalPlugins,\n} from '@tanstack/start-client-core'\nimport { fromJSON, toJSONAsync } from 'seroval'\n\ntype StaticCachedResult = {\n result: any\n context: any\n}\n\n/**\n * This is a simple hash function for generating a hash from a string to make the filenames shorter.\n *\n * It is not cryptographically secure (as its using SHA-1) and should not be used for any security purposes.\n *\n * It is only used to generate a hash for the static cache filenames.\n *\n * @param message - The input string to hash.\n * @returns A promise that resolves to the SHA-1 hash of the input string in hexadecimal format.\n *\n * @example\n * ```typescript\n * const hash = await sha1Hash(\"hello\");\n * console.log(hash); // Outputs the SHA-1 hash of \"hello\" -> \"aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d\"\n * ```\n */\nasync function sha1Hash(message: string): Promise<string> {\n // Encode the string as UTF-8\n const msgBuffer = new TextEncoder().encode(message)\n\n // Hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-1', msgBuffer)\n\n // Convert the ArrayBuffer to a string\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')\n return hashHex\n}\n\nconst getStaticCacheUrl = async (opts: {\n functionId: string\n hash: string\n}) => {\n const filename = await sha1Hash(`${opts.functionId}__${opts.hash}`)\n return `/__tsr/staticServerFnCache/${filename}.json`\n}\n\nconst jsonToFilenameSafeString = (json: any) => {\n // Custom replacer to sort keys\n const sortedKeysReplacer = (key: string, value: any) =>\n value && typeof value === 'object' && !Array.isArray(value)\n ? Object.keys(value)\n .sort()\n .reduce((acc: any, curr: string) => {\n acc[curr] = value[curr]\n return acc\n }, {})\n : value\n\n // Convert JSON to string with sorted keys\n const jsonString = JSON.stringify(json ?? '', sortedKeysReplacer)\n\n // Replace characters invalid in filenames\n return jsonString\n .replace(/[/\\\\?%*:|\"<>]/g, '-') // Replace invalid characters with a dash\n .replace(/\\s+/g, '_') // Optionally replace whitespace with underscores\n}\n\nconst staticClientCache =\n typeof document !== 'undefined' ? new Map<string, any>() : null\n\nasync function addItemToCache({\n functionId,\n data,\n response,\n}: {\n functionId: string\n data: any\n response: StaticCachedResult\n}): Promise<void> {\n {\n const hash = jsonToFilenameSafeString(data)\n const url = await getStaticCacheUrl({ functionId, hash })\n const clientUrl = process.env.TSS_CLIENT_OUTPUT_DIR!\n const filePath = path.join(clientUrl, url)\n\n // Ensure the directory exists\n await fs.mkdir(path.dirname(filePath), { recursive: true })\n\n // Store the result with fs\n const stringifiedResult = JSON.stringify(\n await toJSONAsync(\n {\n result: response.result,\n context: response.context.sendContext,\n },\n { plugins: getDefaultSerovalPlugins() },\n ),\n )\n await fs.writeFile(filePath, stringifiedResult, 'utf-8')\n }\n}\n\nconst fetchItem = async ({\n data,\n functionId,\n}: {\n data: any\n functionId: string\n}) => {\n const hash = jsonToFilenameSafeString(data)\n const url = await getStaticCacheUrl({ functionId, hash })\n\n let result: any = staticClientCache?.get(url)\n\n result = await fetch(url, {\n method: 'GET',\n })\n .then((r) => r.json())\n .then((d) => fromJSON(d, { plugins: getDefaultSerovalPlugins() }))\n\n return result\n}\n\nexport const staticFunctionMiddleware = createMiddleware({ type: 'function' })\n .client(async (ctx) => {\n if (\n process.env.NODE_ENV === 'production' &&\n // do not run this during SSR on the server\n typeof document !== 'undefined'\n ) {\n const response = await fetchItem({\n functionId: ctx.functionId,\n data: ctx.data,\n })\n\n if (response) {\n return {\n result: response.result,\n context: { ...(ctx as any).context, ...response.context },\n } as any\n }\n }\n return ctx.next()\n })\n .server(async (ctx) => {\n const response = await ctx.next()\n if (process.env.NODE_ENV === 'production') {\n await addItemToCache({\n functionId: ctx.functionId,\n response: { result: (response as any).result, context: ctx },\n data: ctx.data,\n })\n }\n\n return response\n })\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/start-static-server-functions",
3
- "version": "1.132.0-alpha.4",
3
+ "version": "1.132.0-alpha.7",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "seroval": "^1.3.2",
47
- "@tanstack/start-client-core": "1.132.0-alpha.4"
47
+ "@tanstack/start-client-core": "1.132.0-alpha.7"
48
48
  },
49
49
  "scripts": {}
50
50
  }
@@ -84,8 +84,8 @@ async function addItemToCache({
84
84
  {
85
85
  const hash = jsonToFilenameSafeString(data)
86
86
  const url = await getStaticCacheUrl({ functionId, hash })
87
- const publicUrl = process.env.TSS_OUTPUT_PUBLIC_DIR!
88
- const filePath = path.join(publicUrl, url)
87
+ const clientUrl = process.env.TSS_CLIENT_OUTPUT_DIR!
88
+ const filePath = path.join(clientUrl, url)
89
89
 
90
90
  // Ensure the directory exists
91
91
  await fs.mkdir(path.dirname(filePath), { recursive: true })