@junejs/db 0.0.34-dev.1 → 0.1.0-dev.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/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/scope.d.ts +2 -1
- package/dist/scope.js +7 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/scope.ts +42 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RequestScope, blob, currentLocale, currentServices, db, ensureScope, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale } from "./scope.js";
|
|
2
|
-
export { type RequestScope, blob, currentLocale, currentServices, db, ensureScope, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale };
|
|
1
|
+
import { RequestScope, blob, currentLocale, currentServices, db, ensureScope, isolateLocal, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale } from "./scope.js";
|
|
2
|
+
export { type RequestScope, blob, currentLocale, currentServices, db, ensureScope, isolateLocal, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { blob, currentLocale, currentServices, db, ensureScope, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale } from "./scope.js";
|
|
2
|
-
export { blob, currentLocale, currentServices, db, ensureScope, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale };
|
|
1
|
+
import { blob, currentLocale, currentServices, db, ensureScope, isolateLocal, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale } from "./scope.js";
|
|
2
|
+
export { blob, currentLocale, currentServices, db, ensureScope, isolateLocal, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale };
|
package/dist/scope.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ type RequestScope = {
|
|
|
9
9
|
declare function ensureScope(): Promise<void>;
|
|
10
10
|
declare function runInScope<T>(scope: RequestScope, fn: () => T): T;
|
|
11
11
|
declare function requestLocal<T>(key: symbol, make: () => T): T;
|
|
12
|
+
declare function isolateLocal<T>(key: string | symbol, make: () => T): T;
|
|
12
13
|
declare function setRequestLocale(locale: string): void;
|
|
13
14
|
declare function currentLocale(): string | undefined;
|
|
14
15
|
declare function currentServices<T = unknown>(): T | undefined;
|
|
@@ -17,4 +18,4 @@ declare const db: JuneDb;
|
|
|
17
18
|
declare const kv: JuneKv;
|
|
18
19
|
declare const blob: JuneBlob;
|
|
19
20
|
//#endregion
|
|
20
|
-
export { RequestScope, blob, currentLocale, currentServices, db, ensureScope, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale };
|
|
21
|
+
export { RequestScope, blob, currentLocale, currentServices, db, ensureScope, isolateLocal, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale };
|
package/dist/scope.js
CHANGED
|
@@ -20,6 +20,12 @@ function requestLocal(key, make) {
|
|
|
20
20
|
if (!locals.has(key)) locals.set(key, make());
|
|
21
21
|
return locals.get(key);
|
|
22
22
|
}
|
|
23
|
+
const ISOLATE_LOCALS_KEY = Symbol.for("june.isolateLocals");
|
|
24
|
+
const isolateLocals = globalThis[ISOLATE_LOCALS_KEY] ??= /* @__PURE__ */ new Map();
|
|
25
|
+
function isolateLocal(key, make) {
|
|
26
|
+
if (!isolateLocals.has(key)) isolateLocals.set(key, make());
|
|
27
|
+
return isolateLocals.get(key);
|
|
28
|
+
}
|
|
23
29
|
function setRequestLocale(locale) {
|
|
24
30
|
const store = als?.getStore();
|
|
25
31
|
if (store) store.locale = locale;
|
|
@@ -59,4 +65,4 @@ const db = new Proxy({}, { get(_t, prop) {
|
|
|
59
65
|
const kv = ambient("kv");
|
|
60
66
|
const blob = ambient("blob");
|
|
61
67
|
//#endregion
|
|
62
|
-
export { blob, currentLocale, currentServices, db, ensureScope, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale };
|
|
68
|
+
export { blob, currentLocale, currentServices, db, ensureScope, isolateLocal, kv, registerSqlTagger, requestLocal, runInScope, setRequestLocale };
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
package/src/scope.ts
CHANGED
|
@@ -95,6 +95,48 @@ export function requestLocal<T>(key: symbol, make: () => T): T {
|
|
|
95
95
|
return locals.get(key) as T;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
// ── isolate-scoped state (the sibling of requestLocal) ────────────────────────
|
|
99
|
+
//
|
|
100
|
+
// `requestLocal` holds state that MUST die with the request. This holds state
|
|
101
|
+
// that must OUTLIVE it: a connection pool, a token cache, a compiled index —
|
|
102
|
+
// anything expensive whose whole value is being reused across requests.
|
|
103
|
+
//
|
|
104
|
+
// It exists because June's own architecture makes the naive version wrong. A
|
|
105
|
+
// ChannelFactory and the `services` provider are resolved PER REQUEST (a Worker
|
|
106
|
+
// has no env at module top-level, so the host must call them inside an
|
|
107
|
+
// invocation). Anything they construct — including a `new Map()` cache — is
|
|
108
|
+
// therefore rebuilt per request, and an app that "added a 5-minute cache"
|
|
109
|
+
// silently never gets a hit. Hoisting to module scope by hand works but has to
|
|
110
|
+
// be re-derived by every app, and a hand-rolled module Map also splits in two
|
|
111
|
+
// when workspace symlinks give the app and the framework different copies of a
|
|
112
|
+
// module. This keys off `globalThis` (the same trick ACTION_REGISTRY uses), so
|
|
113
|
+
// one key means one value per isolate however many module instances load.
|
|
114
|
+
//
|
|
115
|
+
// ⚠ That cross-instance guarantee needs a key with cross-instance identity: a
|
|
116
|
+
// STRING, or `Symbol.for("…")` from the global symbol registry. A plain
|
|
117
|
+
// `Symbol("…")` is a fresh identity in each module instance, so two copies of
|
|
118
|
+
// the module would each make their own value — fine when a single module owns
|
|
119
|
+
// the key privately, wrong if sharing is the point.
|
|
120
|
+
//
|
|
121
|
+
// "Isolate" = the Worker isolate, or the Node/Bun process. Lifetime is the
|
|
122
|
+
// host's, not the request's: values are never evicted here, so anything with a
|
|
123
|
+
// bound (a TTL cache, an LRU) must bound itself.
|
|
124
|
+
//
|
|
125
|
+
// const tokens = isolateLocal("myapp.tokens", () => new Map<string, string>());
|
|
126
|
+
//
|
|
127
|
+
// Keys are namespaced strings (or symbols) — prefix with your app/package name.
|
|
128
|
+
// A key collision returns the FIRST value, so an unprefixed "cache" is a bug
|
|
129
|
+
// waiting to happen across packages.
|
|
130
|
+
const ISOLATE_LOCALS_KEY = Symbol.for("june.isolateLocals");
|
|
131
|
+
const isolateLocals: Map<string | symbol, unknown> = ((
|
|
132
|
+
globalThis as Record<symbol, Map<string | symbol, unknown> | undefined>
|
|
133
|
+
)[ISOLATE_LOCALS_KEY] ??= new Map());
|
|
134
|
+
|
|
135
|
+
export function isolateLocal<T>(key: string | symbol, make: () => T): T {
|
|
136
|
+
if (!isolateLocals.has(key)) isolateLocals.set(key, make());
|
|
137
|
+
return isolateLocals.get(key) as T;
|
|
138
|
+
}
|
|
139
|
+
|
|
98
140
|
// The host sets the resolved locale onto the active scope after it resolves it
|
|
99
141
|
// (the scope is opened before routing, so the locale arrives mid-request). A no-op
|
|
100
142
|
// outside a scope, like the ambient resources.
|