@nubbin/next 0.1.0-rc.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.
- package/LICENSE +21 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +52 -0
- package/package.json +35 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jesse Wheeler
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FieldHintData, ArtifactStore, Artifact } from '@nubbin/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Maps a hole's declared lifecycle onto Next's fetch cache, so the mapping is owned by the
|
|
5
|
+
* binding rather than re-decided in every consumer's resolver. `no-store` also makes a page
|
|
6
|
+
* carrying a request hole dynamic — per-request resolution is exactly what it declared.
|
|
7
|
+
*
|
|
8
|
+
* Takes core's `FieldHintData` directly. An earlier plan derived a local `HoleSpec` from
|
|
9
|
+
* `ArtifactNode["holes"]` so two packages would not import each other; core exports the type
|
|
10
|
+
* by name, so both import it from core and neither derivation is needed.
|
|
11
|
+
*/
|
|
12
|
+
declare function holeFetchOptions(spec: FieldHintData): RequestInit & {
|
|
13
|
+
next?: {
|
|
14
|
+
revalidate: number;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Pointer first, invalidation second. The reverse order re-caches the outgoing page during
|
|
20
|
+
* the gap, and the publish appears to have silently not happened. The store's own publish
|
|
21
|
+
* rejects a hash that was never written, so a failed publish never purges a working page.
|
|
22
|
+
*/
|
|
23
|
+
declare function publishRoute(store: ArtifactStore, route: string, hash: string): Promise<void>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The whole production read path: one pointer read, one artifact read. Null means the caller
|
|
27
|
+
* renders a real 404 — an unpublished route has no pointer, which is what makes unpublish a
|
|
28
|
+
* server 404 rather than an empty page.
|
|
29
|
+
*/
|
|
30
|
+
declare function resolveArtifact(store: ArtifactStore, slug: readonly string[] | undefined): Promise<Artifact | null>;
|
|
31
|
+
|
|
32
|
+
/** Catch-all params to the route string artifacts and pointers are keyed by. */
|
|
33
|
+
declare function routeFromSlug(slug: readonly string[] | undefined): string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* generateStaticParams source. manifest() is an advisory read for exactly this — no request
|
|
37
|
+
* ever goes through it. Non-exact pointers are excluded until #5 settles pattern routing.
|
|
38
|
+
*/
|
|
39
|
+
declare function staticRouteParams(store: ArtifactStore): Promise<{
|
|
40
|
+
slug: string[];
|
|
41
|
+
}[]>;
|
|
42
|
+
|
|
43
|
+
/** Pointer removed, then that one route invalidated — the next request renders a real 404. */
|
|
44
|
+
declare function unpublishRoute(store: ArtifactStore, route: string): Promise<void>;
|
|
45
|
+
|
|
46
|
+
export { holeFetchOptions, publishRoute, resolveArtifact, routeFromSlug, staticRouteParams, unpublishRoute };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// src/holeFetchOptions.ts
|
|
2
|
+
function holeFetchOptions(spec) {
|
|
3
|
+
if (spec === "request") {
|
|
4
|
+
return { cache: "no-store" };
|
|
5
|
+
}
|
|
6
|
+
return { next: { revalidate: spec.revalidate } };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// src/publishRoute.ts
|
|
10
|
+
import { revalidatePath } from "next/cache";
|
|
11
|
+
async function publishRoute(store, route, hash) {
|
|
12
|
+
await store.publish(route, hash);
|
|
13
|
+
revalidatePath(route);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/routeFromSlug.ts
|
|
17
|
+
function routeFromSlug(slug) {
|
|
18
|
+
if (!slug || slug.length === 0) {
|
|
19
|
+
return "/";
|
|
20
|
+
}
|
|
21
|
+
return `/${slug.join("/")}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/resolveArtifact.ts
|
|
25
|
+
async function resolveArtifact(store, slug) {
|
|
26
|
+
const pointer = await store.pointer(routeFromSlug(slug));
|
|
27
|
+
if (!pointer) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return store.read(pointer.hash);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/staticRouteParams.ts
|
|
34
|
+
async function staticRouteParams(store) {
|
|
35
|
+
const { routes } = await store.manifest();
|
|
36
|
+
return routes.filter((pointer) => pointer.matchKind === "exact").map((pointer) => ({ slug: pointer.route.split("/").filter((segment) => segment.length > 0) }));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/unpublishRoute.ts
|
|
40
|
+
import { revalidatePath as revalidatePath2 } from "next/cache";
|
|
41
|
+
async function unpublishRoute(store, route) {
|
|
42
|
+
await store.unpublish(route);
|
|
43
|
+
revalidatePath2(route);
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
holeFetchOptions,
|
|
47
|
+
publishRoute,
|
|
48
|
+
resolveArtifact,
|
|
49
|
+
routeFromSlug,
|
|
50
|
+
staticRouteParams,
|
|
51
|
+
unpublishRoute
|
|
52
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nubbin/next",
|
|
3
|
+
"version": "0.1.0-rc.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@nubbin/core": "0.1.0-rc.0"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"next": ">=16.0.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"next": "16.2.7",
|
|
26
|
+
"tsup": "8.5.1",
|
|
27
|
+
"typescript": "6.0.3",
|
|
28
|
+
"vitest": "4.1.10"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsup",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"typecheck": "tsc --noEmit"
|
|
34
|
+
}
|
|
35
|
+
}
|