@owlmeans/static-resource 0.1.2 → 0.1.3

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.
Files changed (3) hide show
  1. package/README.md +26 -305
  2. package/package.json +6 -5
  3. package/tsconfig.json +5 -4
package/README.md CHANGED
@@ -1,330 +1,51 @@
1
1
  # @owlmeans/static-resource
2
2
 
3
- The **@owlmeans/static-resource** package provides an in-memory resource storage solution for OwlMeans Common Libraries, designed for fullstack microservices and microclients development with focus on security and proper authentication and authorization.
3
+ In-memory `Resource<T>` backed by static config data — for read-only data loaded at startup.
4
4
 
5
- ## Purpose
5
+ ## Overview
6
6
 
7
- This package serves as a lightweight, in-memory resource implementation that:
7
+ - `createStaticResource(alias?, key?)` — creates an in-memory resource populated from config
8
+ - `appendStaticResource(ctx, alias?, key?)` — registers it in the context with a `getStaticResource` accessor
9
+ - `StaticResourceAppend` — mixin type adding `getStaticResource<T>(alias?)` to context
10
+ - Useful for config-driven lookup tables (e.g., product catalogs, permission sets)
8
11
 
9
- - **Provides temporary storage** for resources that don't require persistent storage
10
- - **Supports TTL (Time To Live)** for automatic cleanup of expired records
11
- - **Integrates with context system** for dependency injection and resource management
12
- - **Offers CRUD operations** with validation and error handling
13
- - **Enables testing scenarios** where persistent storage is not needed
12
+ ## Installation
14
13
 
15
- ## Core Concepts
16
-
17
- ### Static Resource
18
- A static resource is an in-memory storage that implements the standard `Resource<ResourceRecord>` interface from `@owlmeans/resource`. It stores records in memory and provides methods for creating, reading, and deleting records.
19
-
20
- ### Key-Value Storage
21
- Records are stored using a key-value approach where each record must have an `id` field. Multiple static resource instances can share the same underlying storage by using the same key.
22
-
23
- ### TTL Support
24
- Records can be created with a Time To Live (TTL) option, after which they are automatically removed from the storage.
25
-
26
- ## API Reference
27
-
28
- ### Factory Functions
29
-
30
- #### `createStaticResource(alias?, key?): Resource<ResourceRecord>`
31
-
32
- Creates a new static resource instance.
33
-
34
- ```typescript
35
- import { createStaticResource } from '@owlmeans/static-resource'
36
-
37
- const resource = createStaticResource('my-cache')
14
+ ```bash
15
+ bun add @owlmeans/static-resource
38
16
  ```
39
17
 
40
- **Parameters:**
41
- - `alias`: string (optional) - Resource alias, defaults to `DEFAULT_ALIAS` ('static')
42
- - `key`: string (optional) - Storage key, defaults to the alias value
43
-
44
- **Returns:** Resource instance implementing full CRUD operations
45
-
46
- #### `appendStaticResource<C, T>(ctx, alias?, key?): T & StaticResourceAppend`
47
-
48
- Adds static resource functionality to a context.
18
+ ## Usage
49
19
 
50
20
  ```typescript
51
21
  import { appendStaticResource } from '@owlmeans/static-resource'
52
- import { makeBasicContext, makeBasicConfig, AppType } from '@owlmeans/context'
53
-
54
- const config = makeBasicConfig(AppType.Backend, 'my-service')
55
- const context = makeBasicContext(config)
56
- const contextWithStatic = appendStaticResource(context, 'cache')
57
- ```
58
-
59
- **Parameters:**
60
- - `ctx`: T - The context to extend
61
- - `alias`: string (optional) - Resource alias, defaults to `DEFAULT_ALIAS`
62
- - `key`: string (optional) - Storage key, defaults to the alias value
63
-
64
- **Returns:** Extended context with `getStaticResource` method
65
-
66
- ### Resource Methods
67
-
68
- The static resource implements the standard `Resource<ResourceRecord>` interface:
69
-
70
- #### `get<T>(id, field?, opts?): Promise<T>`
71
-
72
- Retrieves a record by ID or field value. Throws `UnknownRecordError` if not found.
73
-
74
- ```typescript
75
- const user = await resource.get<User>('user-123')
76
- ```
77
-
78
- #### `load<T>(id, field?, opts?): Promise<T | null>`
79
-
80
- Loads a record by ID or field value. Returns `null` if not found.
81
-
82
- ```typescript
83
- const user = await resource.load<User>('user-123')
84
- if (user) {
85
- console.log('User found:', user.name)
86
- }
87
- ```
88
-
89
- #### `list<T>(criteria?, opts?): Promise<ListResult<T>>`
90
-
91
- Lists all records in the storage.
92
-
93
- ```typescript
94
- const result = await resource.list<User>()
95
- console.log('Total users:', result.items.length)
96
- ```
22
+ import type { StaticResourceAppend } from '@owlmeans/static-resource'
97
23
 
98
- **Note:** Criteria and options parameters are not supported and will throw `UnsupportedArgumentError`.
24
+ appendStaticResource<C, T>(context, 'products')
99
25
 
100
- #### `create<T>(record, opts?): Promise<T>`
101
-
102
- Creates a new record in the storage.
103
-
104
- ```typescript
105
- const user = await resource.create({
106
- id: 'user-123',
107
- name: 'John Doe',
108
- email: 'john@example.com'
109
- }, { ttl: 3600 }) // TTL in seconds
26
+ // Access from context
27
+ const resource = context.getStaticResource<Product>('products')
28
+ const product = await resource.load('product-sku')
110
29
  ```
111
30
 
112
- **Options:**
113
- - `ttl`: number | Date - Time to live in seconds (number) or expiration date (Date)
114
-
115
- **Throws:**
116
- - `UnknownRecordError` - If record doesn't have an `id` field
117
- - `RecordExists` - If record with the same ID already exists
118
-
119
- #### `delete(id, opts?): Promise<T | null>`
120
-
121
- Deletes a record and returns it, or `null` if not found.
122
-
123
- ```typescript
124
- const deletedUser = await resource.delete('user-123')
125
- ```
126
-
127
- #### `pick<T>(id, opts?): Promise<T>`
128
-
129
- Deletes a record and returns it. Throws `UnknownRecordError` if not found.
130
-
131
- ```typescript
132
- const pickedUser = await resource.pick('user-123')
133
- ```
134
-
135
- ### Unsupported Methods
136
-
137
- The following methods throw `UnsupportedMethodError`:
138
- - `save()` - Static resources don't support updating existing records
139
- - `update()` - Static resources don't support partial updates
140
-
141
- ### Types
142
-
143
- #### `StaticResourceAppend`
144
-
145
- Interface added to contexts when using `appendStaticResource`.
146
-
147
- ```typescript
148
- interface StaticResourceAppend {
149
- getStaticResource: <T extends ResourceRecord>(alias?: string) => Resource<T>
150
- }
151
- ```
152
-
153
- #### `Config` and `Context`
154
-
155
- Type aliases for basic context configuration and context interfaces.
156
-
157
- ```typescript
158
- interface Config extends BasicConfig {}
159
- interface Context<C extends Config = Config> extends BasicContext<C> {}
160
- ```
161
-
162
- ### Constants
163
-
164
- #### `DEFAULT_ALIAS`
165
-
166
- Default alias for static resources.
167
-
168
- ```typescript
169
- const DEFAULT_ALIAS = 'static'
170
- ```
171
-
172
- ## Usage Examples
173
-
174
- ### Basic Usage
175
-
176
- ```typescript
177
- import { createStaticResource } from '@owlmeans/static-resource'
178
-
179
- // Create a static resource
180
- const cache = createStaticResource('user-cache')
181
-
182
- // Create records
183
- await cache.create({ id: 'user-1', name: 'Alice', role: 'admin' })
184
- await cache.create({ id: 'user-2', name: 'Bob', role: 'user' })
185
-
186
- // Retrieve records
187
- const alice = await cache.get('user-1')
188
- console.log('Found user:', alice.name)
189
-
190
- // List all records
191
- const { items } = await cache.list()
192
- console.log('Total users:', items.length)
193
-
194
- // Delete a record
195
- const deleted = await cache.delete('user-1')
196
- console.log('Deleted user:', deleted?.name)
197
- ```
198
-
199
- ### Context Integration
200
-
201
- ```typescript
202
- import { appendStaticResource } from '@owlmeans/static-resource'
203
- import { makeBasicContext, makeBasicConfig, AppType } from '@owlmeans/context'
204
-
205
- const config = makeBasicConfig(AppType.Backend, 'user-service')
206
- const context = makeBasicContext(config)
207
-
208
- // Add static resource to context
209
- const enhancedContext = appendStaticResource(context, 'session-cache')
210
-
211
- // Configure and initialize context
212
- enhancedContext.configure()
213
- await enhancedContext.init()
214
-
215
- // Use the static resource
216
- const sessionCache = enhancedContext.getStaticResource('session-cache')
217
- await sessionCache.create({
218
- id: 'session-123',
219
- userId: 'user-456',
220
- expires: new Date(Date.now() + 3600000)
221
- })
222
- ```
223
-
224
- ### TTL Usage
225
-
226
- ```typescript
227
- import { createStaticResource } from '@owlmeans/static-resource'
228
-
229
- const cache = createStaticResource('temporary-cache')
230
-
231
- // Create record with TTL in seconds
232
- await cache.create({
233
- id: 'temp-data',
234
- value: 'This will expire'
235
- }, { ttl: 60 }) // Expires in 60 seconds
236
-
237
- // Create record with expiration date
238
- const expirationDate = new Date(Date.now() + 30000) // 30 seconds from now
239
- await cache.create({
240
- id: 'temp-data-2',
241
- value: 'This will also expire'
242
- }, { ttl: expirationDate })
243
-
244
- // Records will be automatically removed after TTL expires
245
- setTimeout(async () => {
246
- const record = await cache.load('temp-data')
247
- console.log('Record exists:', record !== null) // false
248
- }, 61000)
249
- ```
250
-
251
- ### Shared Storage
252
-
253
- ```typescript
254
- import { createStaticResource } from '@owlmeans/static-resource'
255
-
256
- // Multiple resources sharing the same storage
257
- const cacheA = createStaticResource('cache-a', 'shared-storage')
258
- const cacheB = createStaticResource('cache-b', 'shared-storage')
259
-
260
- // Record created in cacheA is accessible from cacheB
261
- await cacheA.create({ id: 'shared-record', data: 'shared data' })
262
- const record = await cacheB.load('shared-record')
263
- console.log('Shared record:', record?.data) // 'shared data'
264
- ```
265
-
266
- ### Error Handling
267
-
268
- ```typescript
269
- import { createStaticResource } from '@owlmeans/static-resource'
270
- import { UnknownRecordError, RecordExists } from '@owlmeans/resource'
271
-
272
- const resource = createStaticResource('error-demo')
273
-
274
- try {
275
- // This will throw UnknownRecordError
276
- await resource.get('non-existent-id')
277
- } catch (error) {
278
- if (error instanceof UnknownRecordError) {
279
- console.log('Record not found:', error.message)
280
- }
281
- }
282
-
283
- try {
284
- await resource.create({ id: 'user-1', name: 'Alice' })
285
- // This will throw RecordExists
286
- await resource.create({ id: 'user-1', name: 'Bob' })
287
- } catch (error) {
288
- if (error instanceof RecordExists) {
289
- console.log('Record already exists:', error.message)
290
- }
291
- }
292
- ```
31
+ ## API
293
32
 
294
- ## Error Handling
33
+ ### `createStaticResource(alias?, key?): Resource<ResourceRecord>`
295
34
 
296
- The package uses standard error types from `@owlmeans/resource`:
35
+ Creates an in-memory resource. `key` is the config path where data is loaded from.
297
36
 
298
- - **`UnknownRecordError`** - Thrown when trying to access a non-existent record
299
- - **`RecordExists`** - Thrown when trying to create a record with an existing ID
300
- - **`MisshapedRecord`** - Thrown when record structure is invalid (missing ID)
301
- - **`UnsupportedArgumentError`** - Thrown when unsupported arguments are provided
302
- - **`UnsupportedMethodError`** - Thrown when calling unsupported methods
37
+ ### `appendStaticResource<C, T>(ctx, alias?, key?): T & StaticResourceAppend`
303
38
 
304
- ## Integration with OwlMeans Common
39
+ Registers the static resource and adds `getStaticResource` to the context.
305
40
 
306
- This package follows the OwlMeans Common library structure:
307
- - **types**: TypeScript interfaces and type definitions
308
- - **consts**: Static values and constants
309
- - **resource**: Resource implementation and factory functions
41
+ ### `StaticResourceAppend`
310
42
 
311
- The static resource integrates seamlessly with other OwlMeans packages:
312
- - Uses `@owlmeans/context` for dependency injection
313
- - Implements `@owlmeans/resource` interface for consistency
314
- - Supports `@owlmeans/error` error types
43
+ Mixin interface: `getStaticResource<T>(alias?): Resource<T>`
315
44
 
316
- ## Best Practices
45
+ ### `DEFAULT_ALIAS`
317
46
 
318
- 1. **Use for temporary data** - Static resources are perfect for caching, sessions, or test data
319
- 2. **Implement TTL for cleanup** - Always set TTL for records that should expire automatically
320
- 3. **Share storage carefully** - Use the same key only when you want resources to share data
321
- 4. **Handle errors gracefully** - Always catch and handle resource-specific errors
322
- 5. **Integrate with context** - Use `appendStaticResource` for proper context integration
323
- 6. **Test scenarios** - Perfect for unit tests where you don't want persistent storage
47
+ `'static'` — default resource alias.
324
48
 
325
- ## Dependencies
49
+ ## Related Packages
326
50
 
327
- This package depends on:
328
- - `@owlmeans/context` - For contextual resource management
329
- - `@owlmeans/resource` - For resource interface and error types
330
- - `@owlmeans/error` - For error handling infrastructure
51
+ - [`@owlmeans/resource`](../resource) — `Resource<T>` interface implemented here
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/static-resource",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -21,13 +21,14 @@
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
- "@owlmeans/context": "^0.1.2",
25
- "@owlmeans/error": "^0.1.2",
26
- "@owlmeans/resource": "^0.1.2"
24
+ "@owlmeans/context": "^0.1.3",
25
+ "@owlmeans/error": "^0.1.3",
26
+ "@owlmeans/resource": "^0.1.3"
27
27
  },
28
28
  "devDependencies": {
29
+ "@owlmeans/dep-config": "workspace:*",
29
30
  "nodemon": "^3.1.11",
30
- "typescript": "^5.8.3"
31
+ "typescript": "^6.0.2"
31
32
  },
32
33
  "publishConfig": {
33
34
  "access": "public"
package/tsconfig.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "extends": [
3
- "../tsconfig.default.json",
3
+ "@owlmeans/dep-config/tsconfig.base.json",
4
+ "@owlmeans/dep-config/tsconfig.node.json"
4
5
  ],
5
6
  "compilerOptions": {
6
- "rootDir": "./src/", /* Specify the root folder within your source files. */
7
- "outDir": "./build/", /* Specify an output folder for all emitted files. */
7
+ "rootDir": "./src/",
8
+ "outDir": "./build/"
8
9
  },
9
10
  "exclude": [
10
11
  "./dist/**/*",
11
12
  "./build/**/*",
12
13
  "./*.ts"
13
14
  ]
14
- }
15
+ }