anbaric 1.54.0 → 1.56.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/docs/README.md CHANGED
@@ -25,6 +25,7 @@ What the framework gives you, one capability at a time.
25
25
  - [AI agents](features/ai-agents.md) — letting a model drive a state
26
26
  - [Documents and secrets](features/documents-and-secrets.md) — the JSON and secret stores
27
27
  - [The SQL store](features/sql-store.md) — a relational database for structured data
28
+ - [File storage](features/file-storage.md) — bytes at a path, local or in your tenant's storage
28
29
  - [Auditing](features/auditing.md) — the record of who changed what
29
30
  - [Entitlements](features/entitlements.md) — what a user has been granted, checked per request
30
31
  - [Prompts](features/prompts.md) — versioned model instructions and schemas, saved at startup
@@ -52,7 +53,7 @@ The surface you build against.
52
53
  - [TypeScript API](api/typescript.md) — the full app-facing library
53
54
  - [State machines](api/state-machine.md) — `StateMachine`, `State`, `Action`, `Await`, `Transition`, `Job`, `PropertyDefinition`
54
55
  - [Actors and agents](api/actors-and-agents.md) — `Code`, `Human`, `Agent`, AI actions
55
- - [Stores](api/stores.md) — `JsonStore`, `SecretStore`, `SqlStore` and their factories
56
+ - [Stores](api/stores.md) — `JsonStore`, `SecretStore`, `SqlStore`, `FileStorage` and their factories
56
57
  - [Environment and factories](api/environment.md) — the `ANBARIC_*` variables
57
58
  - [Web APIs](api/web.md) — serving HTTP, the app proxy, and the platform endpoints you call
58
59
  - [CLI reference](api/cli.md) — the `anbaric` command
@@ -33,6 +33,7 @@ defaulting to a local implementation otherwise).
33
33
  | `ANBARIC_AUDITOR_TYPE` | the audit sink (`cloud` → platform) | console |
34
34
  | `ANBARIC_JSON_STORE_TYPE` | the JSON document store | in-memory |
35
35
  | `ANBARIC_SECRET_STORE_TYPE` | the secret store | in-memory (encrypted) |
36
+ | `ANBARIC_FILE_STORAGE_TYPE` | the [file storage](../features/file-storage.md) | local disk |
36
37
  | `ANBARIC_SQL_STORE_TYPE` | the SQL store (`sqlite` / `cloud`\|`postgres`) | SQLite |
37
38
  | `ANBARIC_SESSION_RESOLVER_TYPE` | how `Human.fromSession` resolves sessions | in-memory |
38
39
  | `ANBARIC_ENTITLEMENTS_TYPE` | how `hasEntitlement` is answered (`cloud` → platform) | permissive (always `true`) |
@@ -47,6 +48,7 @@ Used by the store implementations the factories return:
47
48
  | `ANBARIC_SQL_FILE` | SQLite | file path to persist to (default `:memory:`) |
48
49
  | `ANBARIC_SQL_DATABASE_URL` | PostgreSQL | connection string |
49
50
  | `ANBARIC_SQL_SCHEMA` | PostgreSQL | schema name (default `anbaric_app_data`) |
51
+ | `ANBARIC_FILE_STORAGE_PATH` | local file storage | directory to keep files in (default `<temp dir>/anbaric/files`) |
50
52
 
51
53
  ## Platform-injected variables
52
54
 
@@ -86,6 +86,37 @@ const key = await secrets.retrieve("stripe-key", actor);
86
86
 
87
87
  ---
88
88
 
89
+ ## `FileStorage`
90
+
91
+ Bytes at a path, with a content type. `list` returns metadata only.
92
+
93
+ ```ts
94
+ FileStorageFactory.instance() : FileStorage
95
+
96
+ // methods:
97
+ put(actor : Actor, path : string, contents : Uint8Array, contentType? : string) : Promise<void>
98
+ get(path : string, actor : Actor) : Promise<StoredFile>
99
+ delete(path : string, actor : Actor) : Promise<void>
100
+ list(prefix : string, actor : Actor) : Promise<Array<StoredFileInfo>>
101
+
102
+ // types:
103
+ StoredFile = { path, contents : Uint8Array, contentType, size, lastModified : Date }
104
+ StoredFileInfo = StoredFile without contents
105
+ ```
106
+
107
+ ```ts
108
+ const files = FileStorageFactory.instance();
109
+ await files.put(actor, "reports/q3.csv", bytes, "text/csv");
110
+ const report = await files.get("reports/q3.csv", actor);
111
+ ```
112
+
113
+ - Paths are relative, `/`-separated, and may not contain `..`.
114
+ - `get` of an unknown path throws `No file found at "..."`.
115
+ - Env var: **`ANBARIC_FILE_STORAGE_TYPE`** (`cloud` deployed; local disk otherwise, under
116
+ `ANBARIC_FILE_STORAGE_PATH` or the temp directory).
117
+
118
+ ---
119
+
89
120
  ## `PromptManager`
90
121
 
91
122
  Versioned prompts - instructions plus an optional output schema - owned by the
@@ -9,7 +9,7 @@ import {
9
9
  StateMachine, State, Terminal, Action, Await, Transition,
10
10
  Job, PropertyDefinition,
11
11
  Code, Human, SystemActor, Agent, OpenAIAgent, AnthropicAgent, GeminiAgent, RemoteLLMAgenticAction,
12
- JsonStoreFactory, SecretStoreFactory, SqlStoreFactory, PromptManagerFactory,
12
+ JsonStoreFactory, SecretStoreFactory, SqlStoreFactory, FileStorageFactory, PromptManagerFactory,
13
13
  registerEntitlement, hasEntitlement,
14
14
  } from "anbaric";
15
15
 
@@ -27,7 +27,7 @@ An Anbaric app is a standard Node.js **ESM** program in TypeScript: set
27
27
  `Actor`.
28
28
  - **[Actors and agents](actors-and-agents.md)** — `Code`, `Human`,
29
29
  `SystemActor`, `Agent`, `RemoteLLMAgenticAction`, `OpenAIAgent`, `AnthropicAgent`, `GeminiAgent`.
30
- - **[Stores](stores.md)** — `JsonStore`, `SecretStore`, `SqlStore`,
30
+ - **[Stores](stores.md)** — `JsonStore`, `SecretStore`, `SqlStore`, `FileStorage`,
31
31
  `PromptManager` and their factories, plus `JsonSchema`.
32
32
  - **[Entitlements](../features/entitlements.md)** — `registerEntitlement`,
33
33
  `hasEntitlement`.
@@ -60,7 +60,7 @@ smaller surface:
60
60
 
61
61
  | Package | Contents |
62
62
  | --- | --- |
63
- | [`anbaric-tsapi`](https://npmjs.com/package/anbaric-tsapi) | Interfaces and value classes: `Job`, `State`, `Action`, `Await`, `Transition`, `Actor`, `JsonStore`, `SecretStore`, `SqlStore`, `Auditor`. |
63
+ | [`anbaric-tsapi`](https://npmjs.com/package/anbaric-tsapi) | Interfaces and value classes: `Job`, `State`, `Action`, `Await`, `Transition`, `Actor`, `JsonStore`, `SecretStore`, `SqlStore`, `FileStorage`, `Auditor`. |
64
64
  | [`anbaric-state-machine`](https://npmjs.com/package/anbaric-state-machine) | `StateMachine`, actors, agents, and in-memory implementations. |
65
65
  | [`anbaric-data-store`](https://npmjs.com/package/anbaric-data-store) | The document, secret and SQL stores. |
66
66
  | [`anbaric-impl-cloud`](https://npmjs.com/package/anbaric-impl-cloud) | The clients used when an app is deployed. |
@@ -66,6 +66,7 @@ You don't — the factories do, from the environment:
66
66
  | --- | --- | --- | --- | --- |
67
67
  | Documents | `JsonStoreFactory.instance(collection, schema?)` | `ANBARIC_JSON_STORE_TYPE` | in-memory | platform (`cloud`) |
68
68
  | Secrets | `SecretStoreFactory.instance()` | `ANBARIC_SECRET_STORE_TYPE` | in-memory (encrypted) | platform (`cloud`) |
69
+ | Files | `FileStorageFactory.instance()` | `ANBARIC_FILE_STORAGE_TYPE` | local disk | platform (`cloud`) |
69
70
 
70
71
  The platform sets these variables when your app is deployed. Don't set them
71
72
  yourself. See [Environment and factories](../api/environment.md).
@@ -81,4 +82,5 @@ automatically.
81
82
  ## Next
82
83
 
83
84
  - [The SQL store](sql-store.md) — a relational database for structured data
85
+ - [File storage](file-storage.md) — bytes at a path
84
86
  - [API: Stores](../api/stores.md)
@@ -0,0 +1,50 @@
1
+ # File storage
2
+
3
+ Some data is a file: a generated report, an uploaded CSV, an image a job
4
+ produced. `FileStorage` keeps bytes at a path, with a content type, and is
5
+ obtained from a factory and used with an actor so every access is audited. Like
6
+ the other stores it's local on your machine and platform-backed once deployed —
7
+ no code change.
8
+
9
+ ## Putting and getting files
10
+
11
+ ```ts
12
+ import {FileStorageFactory} from "anbaric";
13
+
14
+ const files = FileStorageFactory.instance();
15
+
16
+ await files.put(actor, "reports/q3.csv", new TextEncoder().encode("a,b"), "text/csv");
17
+
18
+ const report = await files.get("reports/q3.csv", actor);
19
+ report.contents; // Uint8Array
20
+ report.contentType; // "text/csv"
21
+ report.size; // 3
22
+ report.lastModified; // Date
23
+
24
+ const inReports = await files.list("reports/", actor); // paths, sizes, dates — no contents
25
+ await files.delete("reports/q3.csv", actor);
26
+ ```
27
+
28
+ Paths are plain relative paths with `/` separators — `reports/q3.csv`, never
29
+ `/reports/q3.csv` or anything containing `..`. The content type defaults to
30
+ `application/octet-stream` when you don't give one. Getting an unknown path
31
+ throws `No file found at "..."`.
32
+
33
+ `list` takes a prefix and returns everything under it; pass `""` for every
34
+ file. It returns metadata only, so listing a large store never loads the bytes.
35
+
36
+ ## Where files go
37
+
38
+ **Locally** files live on disk under a temporary directory — `/tmp/anbaric/files`
39
+ on macOS and Linux, the equivalent temp folder on Windows — so a restart keeps
40
+ them and a reboot may not. Point `ANBARIC_FILE_STORAGE_PATH` at a directory to
41
+ keep them somewhere permanent.
42
+
43
+ **Deployed** files live in your tenant's storage, owned by your app: a path is
44
+ private to the app that wrote it, so two apps can use the same path without
45
+ colliding. The **Storage** page in the console lists what each app has stored.
46
+
47
+ ## Next
48
+
49
+ - [Documents and secrets](documents-and-secrets.md) — the JSON and secret stores
50
+ - [API: Stores](../api/stores.md)
@@ -98,6 +98,20 @@ amount.required = true;
98
98
  amount.validation = (v) => typeof v === "number" && v > 0;
99
99
  ```
100
100
 
101
+ Give every property that is not a plain string an **`example`**. The console's
102
+ Start dialog opens on a JSON object built from the schema, and the example is
103
+ what it shows for that property; without one it can only guess from the name,
104
+ and for anything it cannot place it puts `null`. A job started that way then
105
+ runs straight into your actions, so read such properties with a default:
106
+
107
+ ```ts
108
+ const companies = new PropertyDefinition("companies");
109
+ companies.example = [{ slug: "acme", companyName: "Acme Corp" }];
110
+
111
+ // in an action
112
+ const companies = job.properties.get("companies") ?? [];
113
+ ```
114
+
101
115
  ## See also
102
116
 
103
117
  - [State machines](../features/state-machines.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anbaric",
3
- "version": "1.54.0",
3
+ "version": "1.56.0",
4
4
  "description": "Everything needed to write an Anbaric app: state machines, jobs, document and secret stores, local in-memory implementations and the Anbaric Cloud clients",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -24,9 +24,9 @@
24
24
  "prepublishOnly": "npm run build"
25
25
  },
26
26
  "dependencies": {
27
- "anbaric-impl-cloud": "^1.54.0",
28
- "anbaric-data-store": "^1.54.0",
29
- "anbaric-state-machine": "^1.54.0",
30
- "anbaric-tsapi": "^1.54.0"
27
+ "anbaric-impl-cloud": "^1.56.0",
28
+ "anbaric-data-store": "^1.56.0",
29
+ "anbaric-state-machine": "^1.56.0",
30
+ "anbaric-tsapi": "^1.56.0"
31
31
  }
32
32
  }