@xforge-dev/forge-kit 0.18.0 → 0.18.2
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/README.md +16 -0
- package/dist/jobs-provider.js +1 -1
- package/dist/jobs-server.d.ts +3 -1
- package/dist/jobs-server.js +6 -2
- package/dist/jobs-snapshot.js +1 -1
- package/dist/jobs.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,6 +106,22 @@ the sign-in cookie, so a third-party script on one can read every user's session
|
|
|
106
106
|
apps add Vercel Web Analytics (`<Analytics />` from `@vercel/analytics/next` in the root layout);
|
|
107
107
|
it loads from the app's own origin, so the policy needs no extra sources.
|
|
108
108
|
|
|
109
|
+
## Job catalog
|
|
110
|
+
|
|
111
|
+
The kit ships a snapshot of `data/jobs.json` for sync lookups (`job()`, `allJobs()`, ...).
|
|
112
|
+
`refreshJobCatalog()` (from `/server`) fetches the published copy at
|
|
113
|
+
`https://cdn.xforge.dev/data/jobs.json`, caching it for an hour, and installs it. The root layout
|
|
114
|
+
awaits it and passes the result to `ForgeJobsProvider` (from `/client`), so the browser gets the same
|
|
115
|
+
catalog. Whenever `data/jobs.json` changes, set `updated` to a new full ISO-8601 UTC timestamp (for
|
|
116
|
+
example `2026-10-29T18:30:00Z`). CI fails a content change that keeps the old stamp.
|
|
117
|
+
|
|
118
|
+
- **New enum values need a kit release first.** A new `status`, branch or stat value has to ship in
|
|
119
|
+
a kit release, and every app has to bump to that release, before `data/jobs.json` can use the value.
|
|
120
|
+
An older parser rejects the whole file and keeps its snapshot, so no part of the edit reaches that app.
|
|
121
|
+
- **Route handlers and server actions refresh the catalog themselves.** They don't run the root layout,
|
|
122
|
+
so any route handler or server action that looks up jobs must call `await refreshJobCatalog()`
|
|
123
|
+
before its first lookup. Otherwise it only ever sees the snapshot.
|
|
124
|
+
|
|
109
125
|
## Exports
|
|
110
126
|
|
|
111
127
|
`isForgeAuthConfigured` is exported from the root and `/client` entry points.
|
package/dist/jobs-provider.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { getJobCatalog, setJobCatalog } from './jobs.js';
|
|
4
4
|
/** Installs the server-fetched catalog before the children render, so client lookups agree with the server. */
|
|
5
5
|
export function ForgeJobsProvider({ catalog, children }) {
|
|
6
|
-
if (catalog
|
|
6
|
+
if (catalog !== getJobCatalog())
|
|
7
7
|
setJobCatalog(catalog);
|
|
8
8
|
return _jsx(_Fragment, { children: children });
|
|
9
9
|
}
|
package/dist/jobs-server.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type JobCatalog } from './jobs.js';
|
|
2
2
|
/**
|
|
3
3
|
* Fetches the shared job catalog (Next's fetch cache, one hour by default), validates it and installs it
|
|
4
|
-
* as the registry.
|
|
4
|
+
* as the registry. The fetch gives up after `timeoutMs` (default 3s). Any failure, timeout included, leaves the
|
|
5
|
+
* current catalog in place and warns once per distinct error.
|
|
5
6
|
*/
|
|
6
7
|
export declare function refreshJobCatalog(opts?: {
|
|
7
8
|
url?: string;
|
|
8
9
|
revalidate?: number;
|
|
10
|
+
timeoutMs?: number;
|
|
9
11
|
fetch?: typeof fetch;
|
|
10
12
|
}): Promise<JobCatalog>;
|
package/dist/jobs-server.js
CHANGED
|
@@ -2,12 +2,16 @@ import { getJobCatalog, parseJobCatalog, setJobCatalog, JOB_CATALOG_URL } from '
|
|
|
2
2
|
const warned = new Set();
|
|
3
3
|
/**
|
|
4
4
|
* Fetches the shared job catalog (Next's fetch cache, one hour by default), validates it and installs it
|
|
5
|
-
* as the registry.
|
|
5
|
+
* as the registry. The fetch gives up after `timeoutMs` (default 3s). Any failure, timeout included, leaves the
|
|
6
|
+
* current catalog in place and warns once per distinct error.
|
|
6
7
|
*/
|
|
7
8
|
export async function refreshJobCatalog(opts = {}) {
|
|
8
9
|
const doFetch = opts.fetch ?? fetch;
|
|
9
10
|
try {
|
|
10
|
-
const res = await doFetch(opts.url ?? JOB_CATALOG_URL, {
|
|
11
|
+
const res = await doFetch(opts.url ?? JOB_CATALOG_URL, {
|
|
12
|
+
next: { revalidate: opts.revalidate ?? 3600 },
|
|
13
|
+
signal: AbortSignal.timeout(opts.timeoutMs ?? 3000),
|
|
14
|
+
});
|
|
11
15
|
if (!res.ok)
|
|
12
16
|
throw new Error(`job catalog: HTTP ${res.status}`);
|
|
13
17
|
const next = parseJobCatalog(await res.json());
|
package/dist/jobs-snapshot.js
CHANGED
package/dist/jobs.js
CHANGED
|
@@ -115,7 +115,7 @@ export function jobName(name) { return job(name)?.name ?? null; }
|
|
|
115
115
|
export function allJobs(opts = {}) {
|
|
116
116
|
return catalog.jobs
|
|
117
117
|
.filter((j) => opts.includeRetired || j.status !== 'retired')
|
|
118
|
-
.sort((a, b) => a.name.localeCompare(b.name));
|
|
118
|
+
.sort((a, b) => a.name.localeCompare(b.name, 'en'));
|
|
119
119
|
}
|
|
120
120
|
/** Highest Legion rank a character of this level has reached; null below rank B's level. */
|
|
121
121
|
export function legionRankFor(j, level) {
|