@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 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
@@ -1,8 +1,8 @@
1
1
  {
2
- "schemaVersion": 2,
2
+ "schemaVersion": 3,
3
3
  "package": "@owlmeans/static-resource",
4
- "version": "0.1.18-rc.8",
5
- "generatedAt": "2026-09-01T16:28:56.999Z",
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-rc.8"` in `dependencies`
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 and there is nothing here to mint one from, so **every write
44
- needs an id**: `create`, `update` and `save` all throw `MisshapedRecord('id')` without one.
45
- `create` additionally throws `RecordExists`, `update` `UnknownRecordError`; `save` is the upsert.
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` is honoured on writes — a number is seconds from now, a `Date` the instant to expire
55
- at, and the record is dropped from the map when it elapses. An expiry already armed keeps its
56
- appointment: rewriting the record without a ttl does not cancel it, so a renewal passes the ttl
57
- again and a record that must survive gets a fresh id.
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
 
@@ -1 +1 @@
1
- {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAC2B,QAAQ,EAAE,cAAc,EAC9D,MAAM,oBAAoB,CAAA;AAK3B,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAYvE,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,cAAc,GAAG,cAAc,EAC5E,QAAO,MAAsB,EAAE,MAAM,MAAM,KAC1C,QAAQ,CAAC,CAAC,CA4HZ,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EACzE,KAAK,CAAC,EAAE,QAAO,MAAsB,EAAE,MAAM,MAAM,KAClD,CAAC,GAAG,oBAWN,CAAA"}
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 { applyQuery, filterRecords, firstMatch, MisshapedRecord, RecordExists, UnknownRecordError, UnsupportedArgumentError } from '@owlmeans/resource';
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
- throw new MisshapedRecord('id');
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"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"}
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-rc.8",
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-rc.7",
25
- "@owlmeans/error": "^0.1.18-rc.7",
26
- "@owlmeans/resource": "^0.1.18-rc.8"
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": "workspace:*",
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
- applyQuery, filterRecords, firstMatch, MisshapedRecord, RecordExists, UnknownRecordError,
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
- throw new MisshapedRecord('id')
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