@owlmeans/static-resource 0.1.18-rc.8 → 0.1.18
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 +2 -2
- package/agent-meta/manifest.json +3 -3
- package/agent-meta/skills/static-resource/SKILL.md +19 -9
- package/build/resource.d.ts.map +1 -1
- package/build/resource.js +13 -6
- package/build/resource.js.map +1 -1
- package/package.json +5 -5
- package/src/resource.ts +15 -9
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ In-memory `Resource<T>` backed by static config data — for read-only data load
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bun add @owlmeans/static-resource
|
|
15
|
+
bun add @owlmeans/static-resource@^0.1.18
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
@@ -63,7 +63,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
63
63
|
your project's skill store (`.agents/skills/`):
|
|
64
64
|
|
|
65
65
|
```sh
|
|
66
|
-
npx @owlmeans/agent-skills
|
|
66
|
+
npx @owlmeans/agent-skills@^0.1.18
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion":
|
|
2
|
+
"schemaVersion": 3,
|
|
3
3
|
"package": "@owlmeans/static-resource",
|
|
4
|
-
"version": "0.1.18
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18",
|
|
5
|
+
"generatedAt": "2026-10-28T00:31:34.772Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/static-resource
|
|
9
9
|
|
|
10
10
|
**Layer:** Infra
|
|
11
|
-
**Install:** `"@owlmeans/static-resource": "^0.1.18
|
|
11
|
+
**Install:** `"@owlmeans/static-resource": "^0.1.18"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
The whole `Resource` contract over a `Map` held at module scope. Use it where records must be
|
|
14
14
|
reachable through the context like any other resource but have no database behind them — fixtures,
|
|
@@ -40,21 +40,31 @@ await fixtures.list({ name: { $startsWith: 'Owl' } }, { sort: ['name'] })
|
|
|
40
40
|
|
|
41
41
|
## Semantics
|
|
42
42
|
|
|
43
|
-
- The store is a map keyed by id
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
- The store is a map keyed by id. **`create` mints one (`randomUUID()`) when the record carries
|
|
44
|
+
none** — what a Mongo or Postgres `create()` does, so code written against those backends runs
|
|
45
|
+
unchanged over this one — and honours a supplied id, throwing `RecordExists` only when that id is
|
|
46
|
+
already stored. `update` and `save` need an id and throw `MisshapedRecord('id')` without one;
|
|
47
|
+
`update` also throws `UnknownRecordError`, and `save` is the upsert.
|
|
46
48
|
- `load(id)` / `get(id)` / `delete(id)` / `take(id)` hit the map directly. `take(id)` **deletes**
|
|
47
49
|
the record it returns and throws `UnknownRecordError` on a miss.
|
|
48
50
|
- `load(where)`, `get(where)`, `list`, `count` and `purge` go through the shared in-memory engine
|
|
49
51
|
from `@owlmeans/resource`, so criteria and `{ sort }` mean exactly what they mean against a
|
|
50
|
-
database. `purge(where)` refuses an empty criteria object
|
|
52
|
+
database. `purge(where)` refuses an empty criteria object
|
|
53
|
+
(`UnsupportedArgumentError('purge:empty-criteria')` — the database backends spell the same
|
|
54
|
+
refusal `purge:no-criteria`, so match on the error type rather than the message).
|
|
51
55
|
- **Unpaged**: `list(where)` with no `size` returns every match — the whole store is already in
|
|
52
56
|
memory; `size: 0` says the same explicitly, and `page` without `size` throws
|
|
53
57
|
`UnsupportedArgumentError('page-without-size')`.
|
|
54
|
-
- `opts.ttl`
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
- `opts.ttl` on a write arms a timer that deletes the id when it elapses — a number is seconds from
|
|
59
|
+
now, a `Date` the instant to expire at.
|
|
60
|
+
- **An armed expiry cannot be postponed.** Nothing ever clears a timer, so a later write — with a
|
|
61
|
+
ttl or without one — leaves the original running, and when it fires it deletes whatever record now
|
|
62
|
+
sits under that id. Passing the ttl again renews nothing; it only adds a second timer behind the
|
|
63
|
+
first. A record that has to outlive its first ttl needs a fresh id.
|
|
64
|
+
- **The map holds the caller's own object.** `create`/`update`/`save` store the object handed in and
|
|
65
|
+
`load`/`get`/`list` hand it straight back — no clone, no serialization. Mutating a record you
|
|
66
|
+
saved or read rewrites the store in place, bypassing `update` entirely, which is not how the
|
|
67
|
+
database backends behave. Copy before mutating, or treat what comes out of here as frozen.
|
|
58
68
|
|
|
59
69
|
## Depends On
|
|
60
70
|
|
package/build/resource.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAC2B,QAAQ,EAAE,cAAc,EAC9D,MAAM,oBAAoB,CAAA;AAI3B,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAYvE,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,cAAc,GAAG,cAAc,UACrE,MAAM,QAAwB,MAAM,KAC1C,QAAQ,CAAC,CAAC,CAkIZ,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OACpE,CAAC,UAAS,MAAM,QAAwB,MAAM,KAClD,CAAC,GAAG,oBAWN,CAAA"}
|
package/build/resource.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { appendContextual } from '@owlmeans/context';
|
|
2
3
|
import { DEFAULT_ALIAS } from './consts.js';
|
|
3
|
-
import {
|
|
4
|
+
import { MisshapedRecord, RecordExists, recordQueryHelper, UnknownRecordError, UnsupportedArgumentError } from '@owlmeans/resource';
|
|
4
5
|
const stores = {};
|
|
5
6
|
/**
|
|
6
7
|
* Milliseconds until the record expires, which is what `setTimeout` wants. A number is seconds
|
|
@@ -27,7 +28,7 @@ export const createStaticResource = (alias = DEFAULT_ALIAS, key) => {
|
|
|
27
28
|
/** An id hits the map directly; criteria go through the shared in-memory engine. */
|
|
28
29
|
const first = (idOrWhere, opts) => typeof idOrWhere === 'string'
|
|
29
30
|
? getStore().get(idOrWhere) ?? null
|
|
30
|
-
: firstMatch(records(), idOrWhere, opts);
|
|
31
|
+
: recordQueryHelper.firstMatch(records(), idOrWhere, opts);
|
|
31
32
|
const write = (record, opts) => {
|
|
32
33
|
if (record.id == null) {
|
|
33
34
|
/**
|
|
@@ -54,12 +55,18 @@ export const createStaticResource = (alias = DEFAULT_ALIAS, key) => {
|
|
|
54
55
|
if (opts?.page != null && opts.size == null) {
|
|
55
56
|
throw new UnsupportedArgumentError('page-without-size');
|
|
56
57
|
}
|
|
57
|
-
return applyQuery(records(), where, opts);
|
|
58
|
+
return recordQueryHelper.applyQuery(records(), where, opts);
|
|
58
59
|
},
|
|
59
|
-
count: async (where) => filterRecords(records(), where).length,
|
|
60
|
+
count: async (where) => recordQueryHelper.filterRecords(records(), where).length,
|
|
60
61
|
create: async (record, opts) => {
|
|
62
|
+
/**
|
|
63
|
+
* A supplied id is honored (many callers key by a natural id, Redis-style) — but a missing
|
|
64
|
+
* one is minted here rather than rejected, the same as a real Mongo/Postgres `create()`
|
|
65
|
+
* auto-generates its own id when the caller supplies none. Only a supplied id that already
|
|
66
|
+
* exists is `RecordExists`.
|
|
67
|
+
*/
|
|
61
68
|
if (record.id == null) {
|
|
62
|
-
|
|
69
|
+
record = { ...record, id: randomUUID() };
|
|
63
70
|
}
|
|
64
71
|
if (getStore().has(record.id)) {
|
|
65
72
|
throw new RecordExists(record.id);
|
|
@@ -99,7 +106,7 @@ export const createStaticResource = (alias = DEFAULT_ALIAS, key) => {
|
|
|
99
106
|
throw new UnsupportedArgumentError('purge:empty-criteria');
|
|
100
107
|
}
|
|
101
108
|
const store = getStore();
|
|
102
|
-
const matched = filterRecords(records(), where);
|
|
109
|
+
const matched = recordQueryHelper.filterRecords(records(), where);
|
|
103
110
|
matched.forEach(record => record.id != null && store.delete(record.id));
|
|
104
111
|
return matched.length;
|
|
105
112
|
}
|
package/build/resource.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAI3C,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/static-resource",
|
|
3
|
-
"version": "0.1.18
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@owlmeans/context": "^0.1.18
|
|
25
|
-
"@owlmeans/error": "^0.1.18
|
|
26
|
-
"@owlmeans/resource": "^0.1.18
|
|
24
|
+
"@owlmeans/context": "^0.1.18",
|
|
25
|
+
"@owlmeans/error": "^0.1.18",
|
|
26
|
+
"@owlmeans/resource": "^0.1.18"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@owlmeans/dep-config": "
|
|
29
|
+
"@owlmeans/dep-config": "^0.1.18",
|
|
30
30
|
"nodemon": "^3.1.14",
|
|
31
31
|
"typescript": "^7.0.2"
|
|
32
32
|
},
|
package/src/resource.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto'
|
|
1
2
|
import { appendContextual } from '@owlmeans/context'
|
|
2
3
|
import { DEFAULT_ALIAS } from './consts.js'
|
|
3
4
|
import type {
|
|
4
5
|
Criteria, FirstOptions, ListOptions, Resource, ResourceRecord, Ttl, WriteOptions
|
|
5
6
|
} from '@owlmeans/resource'
|
|
6
7
|
import {
|
|
7
|
-
|
|
8
|
-
UnsupportedArgumentError
|
|
8
|
+
MisshapedRecord, RecordExists, recordQueryHelper, UnknownRecordError, UnsupportedArgumentError
|
|
9
9
|
} from '@owlmeans/resource'
|
|
10
10
|
import type { Config, Context, StaticResourceAppend } from './types.js'
|
|
11
11
|
|
|
@@ -46,7 +46,7 @@ export const createStaticResource = <T extends ResourceRecord = ResourceRecord>(
|
|
|
46
46
|
const first = (idOrWhere: string | Criteria<T>, opts?: FirstOptions<T>): T | null =>
|
|
47
47
|
typeof idOrWhere === 'string'
|
|
48
48
|
? getStore().get(idOrWhere) ?? null
|
|
49
|
-
: firstMatch(records(), idOrWhere, opts)
|
|
49
|
+
: recordQueryHelper.firstMatch(records(), idOrWhere, opts)
|
|
50
50
|
|
|
51
51
|
const write = (record: Partial<T>, opts?: WriteOptions): T => {
|
|
52
52
|
if (record.id == null) {
|
|
@@ -81,17 +81,23 @@ export const createStaticResource = <T extends ResourceRecord = ResourceRecord>(
|
|
|
81
81
|
throw new UnsupportedArgumentError('page-without-size')
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
return applyQuery(records(), where, opts)
|
|
84
|
+
return recordQueryHelper.applyQuery(records(), where, opts)
|
|
85
85
|
},
|
|
86
86
|
|
|
87
|
-
count: async (where?: Criteria<T>) => filterRecords(records(), where).length,
|
|
87
|
+
count: async (where?: Criteria<T>) => recordQueryHelper.filterRecords(records(), where).length,
|
|
88
88
|
|
|
89
89
|
create: async (record: Partial<T>, opts?: WriteOptions) => {
|
|
90
|
+
/**
|
|
91
|
+
* A supplied id is honored (many callers key by a natural id, Redis-style) — but a missing
|
|
92
|
+
* one is minted here rather than rejected, the same as a real Mongo/Postgres `create()`
|
|
93
|
+
* auto-generates its own id when the caller supplies none. Only a supplied id that already
|
|
94
|
+
* exists is `RecordExists`.
|
|
95
|
+
*/
|
|
90
96
|
if (record.id == null) {
|
|
91
|
-
|
|
97
|
+
record = { ...record, id: randomUUID() }
|
|
92
98
|
}
|
|
93
|
-
if (getStore().has(record.id)) {
|
|
94
|
-
throw new RecordExists(record.id)
|
|
99
|
+
if (getStore().has(record.id as string)) {
|
|
100
|
+
throw new RecordExists(record.id as string)
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
return write(record, opts)
|
|
@@ -137,7 +143,7 @@ export const createStaticResource = <T extends ResourceRecord = ResourceRecord>(
|
|
|
137
143
|
throw new UnsupportedArgumentError('purge:empty-criteria')
|
|
138
144
|
}
|
|
139
145
|
const store = getStore()
|
|
140
|
-
const matched = filterRecords(records(), where)
|
|
146
|
+
const matched = recordQueryHelper.filterRecords(records(), where)
|
|
141
147
|
matched.forEach(record => record.id != null && store.delete(record.id))
|
|
142
148
|
|
|
143
149
|
return matched.length
|