@astilba/cache 0.0.0-stage → 0.1.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.
@@ -0,0 +1,131 @@
1
+ import { $ as Clock, A as Tier, B as EnvelopeEnc, C as L3Ineligibility, Ct as TelemetrySink, D as RenderCollector, Dt as Watermark, E as PurgeResult, Et as Validity, F as compound, G as Bus, H as Duration, I as globalTag, J as CasOrder, K as BusEvent, L as t, M as createCache, N as Tag, O as RequestContext, P as TagPart, Q as CdnMode, R as ChannelState, S as L3Emission, St as TelemetryEventName, T as OriginLoadGuard, Tt as TagKnowledge, U as DurationUnit, V as EnvelopeKind, W as duration, X as CasStore, Y as CasRecord, Z as Cdn, _ as GetOptions, _t as SinkErrorHook, a as DeleteSelector, at as Registry, b as GracedInfo, bt as TelemetryConfig, c as ExplainDependencyScope, ct as Store, d as ExplainScope, dt as StoreWriteError, et as Codec, f as ExplainTtl, ft as StoreWriteOptions, g as FactoryCtx, gt as memory, h as Explanation, ht as isStoreWriteError, i as CacheEntry, it as ReadKind, j as UnknownPolicy, k as Scope, l as ExplainIdentity, lt as StoreMetadata, m as ExplainedDependency, mt as TagChange, n as CacheConfig, nt as LockHandle, o as EntryFactoryCtx, ot as RegistryAck, p as ExplainVerdict, pt as Subscription, q as BusFrame, r as CacheDefaults, rt as MemoryOptions, s as ExpireSelector, st as Rng, t as Cache, tt as Lock, u as ExplainReaderState, ut as StoreValue, v as GetOrSetEntryOptions, vt as StrongDegradedReason, w as MatchedHint, wt as Consistency, x as L3Budget, xt as TelemetryEvent, y as GetOrSetOptions, yt as TELEMETRY_EVENTS, z as Envelope } from "./cache-YWn0VZpn.js";
2
+ //#region src/errors.d.ts
3
+ /**
4
+ * Thrown by every public entry point during the correctness-kernel phase. A RED
5
+ * invariant that fails with `NotImplementedError` is red for the right reason
6
+ * (the kernel is unimplemented), as opposed to a toolchain/config failure.
7
+ */
8
+ declare class NotImplementedError extends Error {
9
+ constructor(symbol: string);
10
+ }
11
+ /** Whether a cache timeout originated inside the cache or from a caller abort. */
12
+ type CacheTimeoutSource = "cache" | "caller";
13
+ /**
14
+ * Distinguishes cache-originated timeouts (retriable — evidence about origin
15
+ * health) from caller aborts (not evidence of origin health).
16
+ */
17
+ declare class CacheTimeoutError extends Error {
18
+ readonly source: CacheTimeoutSource;
19
+ constructor(source: CacheTimeoutSource, message?: string);
20
+ }
21
+ /**
22
+ * Thrown by a `strong` read when the registry is unreachable. Opt out with
23
+ * `onUnavailable: 'eventual'`.
24
+ */
25
+ declare class RegistryUnavailableError extends Error {
26
+ /**
27
+ * `options.cause` carries the error this one displaced, where there was one. The serve-time
28
+ * re-validation of a graced candidate runs INSIDE a failed fill: if the registry is unreachable
29
+ * there, this error is what the caller sees instead of the factory failure that started it, so
30
+ * the factory failure rides along rather than being dropped. Nothing is lost and callers get one
31
+ * uniform type. Widened additively — `new RegistryUnavailableError(msg)` is unchanged.
32
+ */
33
+ constructor(message?: string, options?: ErrorOptions);
34
+ }
35
+ /**
36
+ * Thrown by a read whose tag knowledge is UNKNOWN under `unknownPolicy: 'error'`.
37
+ *
38
+ * WHAT MAKES THIS DISTINCT FROM A MISS, AND WHY THE DISTINCTION IS THE POINT. Every other
39
+ * fail-closed resolution refills from origin, which is hard-safe exactly when the origin is truth.
40
+ * `'error'` is the policy for the case where it is NOT: a namespace under a takedown or a legal
41
+ * embargo. There, an origin that has not caught up yet can lose a race with the purge and hand back
42
+ * exactly the content that was supposed to vanish. So this policy declines to guess: it neither
43
+ * serves the unknown value nor replaces it
44
+ * with a fresh one, and the caller — who knows what the content is — decides. A policy that resolved
45
+ * to the same refill as `'miss'` would be a switch that reads as protection and does nothing, which
46
+ * is worse than no switch at all.
47
+ *
48
+ * Carries the key and the tags whose knowledge was unknown, so a caller can tell an embargoed
49
+ * dependency from a cold one. EXACTLY those: the tags this read could not establish, and no others.
50
+ * A payload of everything the entry declared cannot answer the question the field exists for — the
51
+ * caller would have to guess which of them was the problem, which is the guess this policy refuses
52
+ * to make on their behalf. Reserved (`__`-prefixed) tags never appear here: they are the kernel's
53
+ * own bookkeeping, they are unknown for exactly the same reason the user's are, and naming them
54
+ * tells the caller nothing they can act on.
55
+ */
56
+ declare class UnknownTagError extends Error {
57
+ readonly key: string;
58
+ readonly tags: readonly string[];
59
+ /**
60
+ * `armedBy` names what selected this resolution — an explicit `unknownPolicy: 'error'`, or the
61
+ * `takedownSensitive` override that outranks it. The message used to state the former
62
+ * unconditionally, which was wrong precisely on the takedown path: the one place where the
63
+ * operator most needs to know which switch fired is the one where the message named the other.
64
+ */
65
+ constructor(key: string, tags: readonly string[], armedBy?: "unknownPolicy" | "takedownSensitive");
66
+ }
67
+ /** A typed HTTP error carrying the offending status and response. */
68
+ declare class HttpError extends Error {
69
+ readonly status: number;
70
+ readonly response: Response;
71
+ constructor(response: Response);
72
+ }
73
+ /**
74
+ * Thrown at the `getOrSet`/`getOrSetEntry` write boundary when a caller-supplied
75
+ * tag is malformed — in particular a user tag beginning with the reserved `__`
76
+ * prefix. A real runtime error, never `NotImplementedError`: tag
77
+ * validation is not deferred kernel logic.
78
+ */
79
+ declare class InvalidTagError extends Error {
80
+ readonly tag: string;
81
+ constructor(tag: string, reason: string);
82
+ }
83
+ /**
84
+ * Thrown by `duration()` when a computed duration is malformed — a non-positive or
85
+ * non-finite `value`, or (critical case) a `value × unitFactor` product that
86
+ * is not a finite, positive, safe integer once multiplied out. A real
87
+ * runtime error, never `NotImplementedError`: duration validation is not deferred kernel
88
+ * logic. Mirrors `InvalidTagError` — the builder rejects a bad input, it never coerces one.
89
+ */
90
+ declare class InvalidDurationError extends Error {
91
+ readonly value: number;
92
+ readonly unit: string;
93
+ constructor(value: number, unit: string, reason: string);
94
+ }
95
+ /**
96
+ * Thrown by the plain `getOrSet` form when a fill is fenced past its write-back
97
+ * retry attempt budget: a hard delete keeps landing mid-fill/mid-
98
+ * refresh so the accepted result never postdates every purge visible at
99
+ * write-back, and the fill fails within its attempt budget rather than ever
100
+ * storing or serving a fenced value. A real runtime outcome, never
101
+ * `NotImplementedError` — the entry form (`getOrSetEntry`) surfaces the same
102
+ * outcome as `{ value: undefined }` instead of throwing.
103
+ */
104
+ declare class FencedError extends Error {
105
+ readonly key: string;
106
+ constructor(key: string, message?: string);
107
+ }
108
+ /**
109
+ * Thrown when a factory declares a dependency after it has settled: a
110
+ * `ctx.dependsOn`/`ctx.setTags` call reaching the context AFTER the factory promise
111
+ * resolved or rejected. The fill's tag set closes at settle, so a later declaration is
112
+ * outside the value's lifetime and cannot join it. A real runtime error, never
113
+ * `NotImplementedError`. Carries the offending key.
114
+ */
115
+ declare class FactorySettledError extends Error {
116
+ readonly key: string;
117
+ constructor(key: string);
118
+ }
119
+ //#endregion
120
+ //#region src/http.d.ts
121
+ /** Wrap a non-ok `Response` into a typed `HttpError`. */
122
+ declare function httpError(response: Response): HttpError;
123
+ /**
124
+ * The default `staleIfError` predicate — retriable: the default
125
+ * retriable set, network errors, and cache-originated timeouts. `404/410/403` are
126
+ * facts, never masked (never retriable) — a caller-abort `CacheTimeoutError` with
127
+ * `source:'caller'` is likewise not evidence of origin health.
128
+ */
129
+ declare function isRetriableHttp(err: unknown): boolean;
130
+ //#endregion
131
+ export { type Bus, type BusEvent, type BusFrame, type Cache, type CacheConfig, type CacheDefaults, type CacheEntry, CacheTimeoutError, type CacheTimeoutSource, type CasOrder, type CasRecord, type CasStore, type Cdn, type CdnMode, type ChannelState, type Clock, type Codec, type Consistency, type DeleteSelector, type Duration, type DurationUnit, type EntryFactoryCtx, type Envelope, type EnvelopeEnc, type EnvelopeKind, type ExpireSelector, type ExplainDependencyScope, type ExplainIdentity, type ExplainReaderState, type ExplainScope, type ExplainTtl, type ExplainVerdict, type ExplainedDependency, type Explanation, type FactoryCtx, FactorySettledError, FencedError, type GetOptions, type GetOrSetEntryOptions, type GetOrSetOptions, type GracedInfo, HttpError, InvalidDurationError, InvalidTagError, type L3Budget, type L3Emission, type L3Ineligibility, type Lock, type LockHandle, type MatchedHint, type MemoryOptions, NotImplementedError, type OriginLoadGuard, type PurgeResult, type ReadKind, type Registry, type RegistryAck, RegistryUnavailableError, type RenderCollector, type RequestContext, type Rng, type Scope, type SinkErrorHook, type Store, type StoreMetadata, type StoreValue, type StoreWriteError, type StoreWriteOptions, type StrongDegradedReason, type Subscription, TELEMETRY_EVENTS, type Tag, type TagChange, type TagKnowledge, type TagPart, type TelemetryConfig, type TelemetryEvent, type TelemetryEventName, type TelemetrySink, type Tier, type UnknownPolicy, UnknownTagError, type Validity, type Watermark, compound, createCache, duration, globalTag, httpError, isRetriableHttp, isStoreWriteError, memory, t };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import { A as UnknownTagError, C as FactorySettledError, D as InvalidTagError, E as InvalidDurationError, O as NotImplementedError, S as CacheTimeoutError, T as HttpError, _ as t, c as isRetriableHttp, d as memory, g as globalTag, h as compound, k as RegistryUnavailableError, l as duration, p as TELEMETRY_EVENTS, r as createCache, s as httpError, u as isStoreWriteError, w as FencedError } from "./cache-Z4cJzPmm.js";
2
+ export { CacheTimeoutError, FactorySettledError, FencedError, HttpError, InvalidDurationError, InvalidTagError, NotImplementedError, RegistryUnavailableError, TELEMETRY_EVENTS, UnknownTagError, compound, createCache, duration, globalTag, httpError, isRetriableHttp, isStoreWriteError, memory, t };
package/package.json CHANGED
@@ -1,6 +1,99 @@
1
1
  {
2
2
  "name": "@astilba/cache",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "Portable TypeScript caching with tag invalidation, stale-if-error resilience, and privacy scopes.",
5
+ "homepage": "https://astilba.com/docs/cache/",
6
+ "bugs": {
7
+ "url": "https://github.com/astilbahq/astilba/issues"
8
+ },
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/astilbahq/astilba.git",
13
+ "directory": "packages/cache"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "type": "module",
19
+ "sideEffects": false,
20
+ "main": "./dist/index.js",
21
+ "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ },
28
+ "./cloudflare": {
29
+ "types": "./dist/adapters/cloudflare/index.d.ts",
30
+ "default": "./dist/adapters/cloudflare/index.js"
31
+ },
32
+ "./react-router": {
33
+ "types": "./dist/adapters/react-router/index.d.ts",
34
+ "default": "./dist/adapters/react-router/index.js"
35
+ },
36
+ "./package.json": "./package.json"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "devDependencies": {
42
+ "@arethetypeswrong/cli": "0.18.4",
43
+ "@cloudflare/vitest-pool-workers": "0.18.3",
44
+ "@fast-check/vitest": "^0.4.1",
45
+ "@stryker-mutator/core": "9.6.1",
46
+ "@stryker-mutator/vitest-runner": "9.6.1",
47
+ "@types/node": "24.13.2",
48
+ "@types/react": "19.2.17",
49
+ "@vitest/coverage-istanbul": "4.1.11",
50
+ "eslint-plugin-github": "6.0.0",
51
+ "eslint-plugin-sonarjs": "4.1.0",
52
+ "fast-check": "^4.8.0",
53
+ "knip": "6.24.0",
54
+ "miniflare": "4.20260708.0",
55
+ "oxfmt": "0.64.0",
56
+ "oxlint": "1.79.0",
57
+ "oxlint-tsgolint": "7.0.2001",
58
+ "publint": "0.3.21",
59
+ "react": "19.2.7",
60
+ "react-router": "8.3.0",
61
+ "typescript": "6.0.3",
62
+ "ultracite": "7.9.2",
63
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
64
+ "vite-plus": "0.3.0",
65
+ "vitest": "4.1.11",
66
+ "wrangler": "4.109.0",
67
+ "yaml": "2.9.0",
68
+ "@astilba/harness": "0.0.0"
69
+ },
70
+ "peerDependencies": {
71
+ "react": "19.2.7",
72
+ "react-router": "8.3.0"
73
+ },
74
+ "peerDependenciesMeta": {
75
+ "react": {
76
+ "optional": true
77
+ },
78
+ "react-router": {
79
+ "optional": true
80
+ }
81
+ },
82
+ "scripts": {
83
+ "build": "vp pack",
84
+ "build:apps": "pnpm --dir ../../fixtures/cache-react-router run build && pnpm --dir ../../apps/cache-demo run build",
85
+ "check": "for d in . ../cache-harness ../../apps/cache-demo; do (cd $d && oxfmt --config oxfmt.config.ts --disable-nested-config --check . && oxlint --config oxlint.config.ts --disable-nested-config --type-aware --type-check .) || exit 1; done",
86
+ "fix": "for d in . ../cache-harness ../../apps/cache-demo; do (cd $d && oxfmt --config oxfmt.config.ts --disable-nested-config --write . && oxlint --config oxlint.config.ts --disable-nested-config --type-aware --type-check --fix .) || exit 1; done",
87
+ "test": "vp test",
88
+ "test:unit": "vp test run --project unit --project harness",
89
+ "test:invariants": "vitest run --project invariants",
90
+ "test:mutation": "stryker run",
91
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.config.json && tsc -p test/integration/tsconfig.json --noEmit && pnpm --filter @astilba/harness --filter @astilba/demo --filter @astilba/rr-fixture -r exec tsc --noEmit",
92
+ "types:integration": "cd test/integration && wrangler types",
93
+ "lint:publish": "node scripts/check-package.mjs",
94
+ "knip": "pnpm --dir ../.. exec knip --workspace packages/cache --workspace packages/cache-harness --workspace apps/cache-demo --workspace fixtures/cache-react-router",
95
+ "knip:production": "pnpm knip --production",
96
+ "verify:toolchain": "node scripts/verify-toolchain.mjs",
97
+ "verify": "pnpm verify:toolchain && pnpm check && pnpm typecheck && pnpm exec vitest run && pnpm exec vp test run --project unit --project harness --coverage && pnpm lint:publish && pnpm knip && pnpm knip:production && pnpm build:apps && node scripts/boot-smoke.mjs && node scripts/module-scope-boot.mjs && node scripts/demo-boot-witness.mjs && node scripts/demo-typed-routes.mjs"
98
+ }
6
99
  }