@basaltkit/cache 1.2.1 → 1.3.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/README.md +1 -0
- package/dist/index.js +11 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -211,6 +211,7 @@ const cacheB = new Cache(new RedisCacheDriver(redis))
|
|
|
211
211
|
|---|---|---|---|---|
|
|
212
212
|
| `prefix` | `string` | No | `'basalt'` | Root prefix for all keys. |
|
|
213
213
|
| `scope` | `(() => string \| undefined) \| null` | No | reads `ctx().tenant.id` → `tenant:<id>` | Dynamic prefix segment, resolved on each operation. `null` disables tenant isolation. |
|
|
214
|
+
| `onMissingScope` | `'global' \| 'error'` | No | `'error'` when `tenancyPlugin` is registered, else `'global'` | What an operation does when the scope resolves to `undefined` (e.g. a background job outside request context). In multi-tenant apps the default fails CLOSED (`MissingCacheScopeError`) instead of silently sharing one namespace across tenants; single-tenant apps keep the global namespace. Explicit values always win. |
|
|
214
215
|
|
|
215
216
|
### `cachePlugin(options?: CachePluginOptions)`
|
|
216
217
|
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BasaltError, createToken, definePlugin, parseDuration, tryCtx, } from '@basaltkit/core';
|
|
1
|
+
import { BasaltError, createToken, definePlugin, ensureMetadata, parseDuration, tryCtx, } from '@basaltkit/core';
|
|
2
2
|
import { MemoryCacheDriver } from './drivers/memory.js';
|
|
3
3
|
import { RedisCacheDriver } from './drivers/redis.js';
|
|
4
4
|
export { MemoryCacheDriver } from './drivers/memory.js';
|
|
@@ -169,7 +169,16 @@ export function cachePlugin(options = {}) {
|
|
|
169
169
|
: options.driver === 'redis'
|
|
170
170
|
? RedisCacheDriver.fromUrl(options.url)
|
|
171
171
|
: new MemoryCacheDriver();
|
|
172
|
-
|
|
172
|
+
// Fail closed by default in multi-tenant apps: when @basaltkit/tenancy
|
|
173
|
+
// is registered (its 'tenancy:active' metadata marker), an operation
|
|
174
|
+
// with no resolvable tenant scope throws instead of silently sharing
|
|
175
|
+
// one global namespace across tenants. Single-tenant apps (no tenancy)
|
|
176
|
+
// are untouched, and an explicit `onMissingScope`/custom `scope` wins.
|
|
177
|
+
const tenancyActive = ensureMetadata(container).get('tenancy:active').length > 0;
|
|
178
|
+
const resolved = options.onMissingScope === undefined && options.scope === undefined && tenancyActive
|
|
179
|
+
? { ...options, onMissingScope: 'error' }
|
|
180
|
+
: options;
|
|
181
|
+
return new Cache(driver, resolved);
|
|
173
182
|
});
|
|
174
183
|
},
|
|
175
184
|
async shutdown() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basaltkit/cache",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Basalt cache layer: Redis and Memory drivers, tags, TTL, stampede protection and automatic per-tenant isolation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"ioredis": "^6.0.0",
|
|
18
|
-
"@basaltkit/core": "^1.
|
|
18
|
+
"@basaltkit/core": "^1.3.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^26.3.0",
|