arkiv-images 1.0.4 → 1.0.5
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/AGENTS.md +2 -2
- package/CHANGELOG.md +7 -0
- package/README.md +8 -6
- package/dist/index.d.ts +4 -1
- package/dist/index.js +5 -2
- package/docs/verification.md +4 -2
- package/package.json +6 -4
- package/sample/AGENTS.md +1 -1
- package/sample/README.md +5 -3
package/AGENTS.md
CHANGED
|
@@ -2,11 +2,11 @@ Edit instructions only in AGENTS.md; CLAUDE.md only imports this file.
|
|
|
2
2
|
|
|
3
3
|
# Integrating arkiv-images
|
|
4
4
|
|
|
5
|
-
Read [README.md](README.md) explicitly for the public API, runnable local example, data model, limits, signing and recovery. Install version 1.0.
|
|
5
|
+
Read [README.md](README.md) explicitly for the public API, runnable local example, data model, limits, signing and recovery. Install version 1.0.5 with `npm install arkiv-images@1.0.5 @arkiv-network/sdk@1.0.1 viem@2.56.3`.
|
|
6
6
|
|
|
7
7
|
- Ask whether the task needs local inspection, retrieval or a new public upload. Inspection requires no network. Retrieval needs an image key, Rabdi and optionally an independently trusted SHA-256. Writes additionally require a locally configured signing wallet and test funds.
|
|
8
8
|
- Ask whether original bytes, filename and metadata are safe to publish. EXIF/GPS is preserved. Stop if confidentiality is required; encryption is a different tool.
|
|
9
|
-
- Use Rabdi chain 7794095 with SDK 1.0.0. Ask for an explicit Entity Expiration within the admitted block range. Access keys and test funds come from the Hub links in README. Never request a private key in chat.
|
|
9
|
+
- Use Rabdi chain 7794095 with SDK `^1.0.0`, verified with 1.0.1. Ask for an explicit Entity Expiration within the admitted block range. The 7,883,970-block upper bound is this package's file admission limit, kept for compatibility with files already written; not the SDK/chain maximum of 7,884,000 blocks or a requirement of Rabdi. Access keys and test funds come from the Hub links in README. Never request a private key in chat.
|
|
10
10
|
- Import only public package APIs. Reuse arkiv-chunking's publicly exported write policy; no private dependency imports or copied storage/chunking/gas logic. Bytes use non-indexed bytes columns; query only indexed typed metadata with SDK predicates.
|
|
11
11
|
- Preserve MIME/size/network/integrity/decode checks and public TypeScript types. A browser must decode before upload and after retrieval, render only PNG/JPEG, treat filenames as text and revoke Blob URLs.
|
|
12
12
|
- Every write uses unsigned latest-state estimation, explicit gas/price/latest nonce and at least twice estimate, at or below half the head block gas limit. Do not use unlimited lifetime or historical state reads. Never automatically retry successful or uncertain writes.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.5
|
|
4
|
+
|
|
5
|
+
- Verify the SDK `^1.0.0` peer with 1.0.1 and pin development, consumers and the sample SDK to 1.0.1.
|
|
6
|
+
- Update current install guidance, expiry and gas-error behavior; preserve historical evidence.
|
|
7
|
+
- Add current-guidance, packed-content and SDK peer compatibility checks with negative mutations.
|
|
8
|
+
- Pin root and sample dependencies to published arkiv-chunking 1.1.4; retain the independent registry sample dependency.
|
|
9
|
+
|
|
3
10
|
## 1.0.4
|
|
4
11
|
|
|
5
12
|
- Pin arkiv-chunking 1.1.3 so every inherited write enforces half the fresh latest block gas limit, including the single allowed retry.
|
package/README.md
CHANGED
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
Store a public PNG or JPEG as queryable Arkiv entities, then retrieve its original bytes with size, MIME, dimensions and SHA-256 checks. Small images use one entity with a non-indexed `bytes()` column. Larger images use `arkiv-chunking`: an image entity references a file manifest and ordered immutable chunks.
|
|
4
4
|
|
|
5
|
-
**arkiv-images 1.0.
|
|
5
|
+
**arkiv-images 1.0.5 targets Rabdi testnet.** It stores PNG/JPEG binary data in `bytes` columns. See [verification](docs/verification.md) for reproducible checks and separately labelled historical observations.
|
|
6
6
|
|
|
7
7
|
## Install and inspect
|
|
8
8
|
|
|
9
|
-
ESM, Node 22.10+ with Web Crypto, or a browser on HTTPS/localhost. Dependencies: SDK 1.0.0, viem 2.56.3, arkiv-chunking 1.1.
|
|
9
|
+
ESM, Node 22.10+ with Web Crypto, or a browser on HTTPS/localhost. Dependencies: SDK `^1.0.0`, verified with 1.0.1, viem 2.56.3, arkiv-chunking 1.1.4.
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
12
|
mkdir image-consumer
|
|
13
13
|
cd image-consumer
|
|
14
14
|
npm init -y
|
|
15
15
|
npm pkg set type=module
|
|
16
|
-
npm install arkiv-images@1.0.
|
|
16
|
+
npm install arkiv-images@1.0.5 @arkiv-network/sdk@1.0.1 viem@2.56.3
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Save `inspect.mjs`:
|
|
@@ -76,16 +76,18 @@ Run `node roundtrip.mjs` after configuring those environment variables locally.
|
|
|
76
76
|
| `ImageSchema`, `IMAGE_TYPE` | SDK 1.0 named schema `arkiv-images/v2`. Binary `data` is stored without an index. Indexed type/mode/mime/sha256/manifest support discovery. Filename, size and dimensions are stored typed columns. |
|
|
77
77
|
| `ImageStorageError`, `ChunkingError` | Safe code/message; preserve imageKey/manifestKey and transactionHashes on failure. Raw causes can include provider details: never display or log them. |
|
|
78
78
|
| `TransactionParameterPolicy`, `Progress` | Public TypeScript integration types re-exported from chunking. |
|
|
79
|
-
| `VERSION`, `INLINE_MAX_BYTES`, `MAX_IMAGE_BYTES`, `MAX_IMAGE_PIXELS`, `MAX_EXPIRATION_BLOCKS`, `RABDI_MAX_LIFETIME_BLOCKS`, `EXPIRATION_INCLUSION_MARGIN_BLOCKS` | Implementation version (`1.0.
|
|
79
|
+
| `VERSION`, `INLINE_MAX_BYTES`, `MAX_IMAGE_BYTES`, `MAX_IMAGE_PIXELS`, `MAX_EXPIRATION_BLOCKS`, `RABDI_MAX_LIFETIME_BLOCKS`, `EXPIRATION_INCLUSION_MARGIN_BLOCKS` | Implementation version (`1.0.5`) and enforced limits. MAX_EXPIRATION_BLOCKS is the package file admission limit; EXPIRATION_INCLUSION_MARGIN_BLOCKS is a legacy public name for the 30-block difference, not a Rabdi requirement. |
|
|
80
80
|
|
|
81
81
|
Import types such as `ImageInfo`, `ImagePlan`, `StoreImageOptions`, `StoredImage`, `RetrieveImageOptions`, `RetrievedImage`, `ImageContentType` and `ImageErrorCode` directly from `arkiv-images`.
|
|
82
82
|
|
|
83
83
|
Limits: **120,000 bytes** inline; **25 MiB** per image; **40,000,000 pixels**. Chunking uses 100,000-byte slices. Larger files require N+3 transactions for N chunks. `planImage` computes this count. These are package admission limits, not a promise of every node's transaction budget.
|
|
84
84
|
|
|
85
|
-
Entity Expiration is whole blocks, at least `max(64, transactionCount + 32)` and at most **7,883,970
|
|
85
|
+
Entity Expiration is whole blocks, at least `max(64, transactionCount + 32)` and at most **7,883,970**. This package's file admission limit is 7,883,970 blocks, kept for compatibility with files already written. It is not the SDK or chain maximum of 7,884,000 blocks and is not a requirement of Rabdi. There is no unlimited lifetime. Longer storage requires coordinated Lifetime Extension outside this API. For a standalone SDK 1.0.1+ entity, `ExpirationTime.max()` selects the longest lifetime from its landing block without subtraction. Sharing an absolute deadline does not require subtracting 30 blocks. Applying `max()` independently to each part would produce different deadlines. The image root and manifest use the same absolute deadline; retrieval rejects independent deadline changes. Root existence alone does not guarantee availability of every chunk.
|
|
86
86
|
|
|
87
87
|
## Signing and recovery
|
|
88
88
|
|
|
89
|
+
SDK 1.0.1 rejects an over-maximum SDK expiry before sending with `InvalidExpiryError`; the prior SDK version could revert on chain with `ExpiryBeyondMaxLifetime`. Image admission rejects out-of-range block lifetimes before either SDK path. SDK 1.0.1 also adds default gas headroom and reports gas exhaustion with `EntityMutationError`. Neither replaces the explicit write recipe or receipt-based retry authorization below.
|
|
90
|
+
|
|
89
91
|
Every part and the final root reuse the public `arkiv-chunking` write policy: an unsigned SDK request is estimated at `latest`; gas is at least `max(1_000_000, 2 × estimate)`, with explicit network gasPrice and a fresh latest nonce. The image API additionally stops before signing if that budget exceeds half the latest block gas limit. Longer expiration can substantially increase gas, so shorten Entity Expiration or choose a smaller image if the estimate exceeds that budget. Admitted byte/lifetime limits do not guarantee every combination fits the network's gas budget. `txParams` can increase gas or change fees; it cannot remove required headroom or override the latest nonce. Wallet account/network are checked before every signature.
|
|
90
92
|
|
|
91
93
|
Serialize writes from the same account. A retry is permitted only once after an authoritative gas-exhausted reverted receipt and only within the half-block gas ceiling. Successful or uncertain writes are never automatically resent. `CONFIRMATION_PENDING` preserves a known submission hash, including one recovered by the shared policy from a wrapped SDK error, plus any available root/manifest keys. SDK-success results enter `submitted` before the receipt recheck; a known-hash SDK error enters `submitted` when the shared policy returns its unresolved confirmation. Observed hashes are recovery evidence, not proof of successful receipts. Browser consumers must keep a `createImageWriteOperation` object across renders and later clicks; `storeImage` is a one-call convenience for an intentional new upload. Inspect preserved receipts before explicitly creating another operation. The sample resets the operation only when you choose a file again. Other failures can also leave confirmed entities. There is no multi-transaction atomicity, rollback, resumable upload, independent part mutation/transfer/extension or automatic cleanup.
|
|
@@ -109,7 +111,7 @@ The package checks containers, not full PNG CRC/JPEG entropy decoding or malware
|
|
|
109
111
|
|
|
110
112
|
## Sample and development
|
|
111
113
|
|
|
112
|
-
The [sample README](sample/README.md) explains the existing `arkiv-images-example` project and visitor-wallet setup. Reads use its own bounded `/api/rpc` endpoint and a server-side `ARKIV_ACCESS_KEY`; the visitor configures their own wallet RPC. No server signer. The sample pins the released registry package `arkiv-images@1.0.
|
|
114
|
+
The [sample README](sample/README.md) explains the existing `arkiv-images-example` project and visitor-wallet setup. Reads use its own bounded `/api/rpc` endpoint and a server-side `ARKIV_ACCESS_KEY`; the visitor configures their own wallet RPC. No server signer. The sample pins the released registry package `arkiv-images@1.0.4`, independently of the library version above.
|
|
113
115
|
|
|
114
116
|
Give consumer agents [AGENTS.md](AGENTS.md) and [sample/AGENTS.md](sample/AGENTS.md) explicitly. The corresponding CLAUDE.md files only import those guides.
|
|
115
117
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Column, type Schema, type TypeTag } from '@arkiv-network/sdk/schema';
|
|
2
2
|
import { type TransactionParameterPolicy, type ChunkingPublicClient, type ChunkingWalletClient, type Progress } from 'arkiv-chunking';
|
|
3
3
|
import { type Hex } from 'viem';
|
|
4
|
-
export declare const VERSION = "1.0.
|
|
4
|
+
export declare const VERSION = "1.0.5";
|
|
5
5
|
export declare const IMAGE_TYPE = "arkiv-images/v2";
|
|
6
6
|
type Stored<T extends TypeTag> = Column<T, false, false, false>;
|
|
7
7
|
type Indexed<T extends TypeTag> = Column<T, true, false, false>;
|
|
@@ -17,6 +17,9 @@ export declare const ImageSchema: Schema<{
|
|
|
17
17
|
manifest: Column<'key', true, true, false>;
|
|
18
18
|
data: Stored<'bytes'>;
|
|
19
19
|
}>;
|
|
20
|
+
/** File admission limit: 7,883,970 blocks, retained for compatibility with files already
|
|
21
|
+
* written; not the SDK/chain maximum of 7,884,000 or a requirement of Rabdi.
|
|
22
|
+
* EXPIRATION_INCLUSION_MARGIN_BLOCKS retains its legacy public name only. */
|
|
20
23
|
export { MAX_EXPIRATION_BLOCKS, RABDI_MAX_LIFETIME_BLOCKS, EXPIRATION_INCLUSION_MARGIN_BLOCKS } from 'arkiv-chunking';
|
|
21
24
|
export declare const INLINE_MAX_BYTES = 120000;
|
|
22
25
|
export declare const MAX_IMAGE_BYTES: number;
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,15 @@ import { bytes as binary, defineSchema, key, str, u64 } from '@arkiv-network/sdk
|
|
|
3
3
|
import { eq } from '@arkiv-network/sdk/query';
|
|
4
4
|
import { uploadFile, downloadFile, hashFile, ChunkingError, DEFAULT_CHUNK_BYTES, MAX_EXPIRATION_BLOCKS, writeWithPolicy, WriteConfirmationPendingError } from 'arkiv-chunking';
|
|
5
5
|
import { hexToBytes } from 'viem';
|
|
6
|
-
export const VERSION = '1.0.
|
|
6
|
+
export const VERSION = '1.0.5';
|
|
7
7
|
export const IMAGE_TYPE = 'arkiv-images/v2';
|
|
8
8
|
export const ImageSchema = defineSchema(IMAGE_TYPE, {
|
|
9
9
|
type: str().indexed(), mode: str().indexed(), mime: str().indexed(), sha256: str().indexed(),
|
|
10
10
|
filename: str(), size: u64(), width: u64(), height: u64(), manifest: key().indexed().optional(), data: binary(),
|
|
11
11
|
});
|
|
12
|
+
/** File admission limit: 7,883,970 blocks, retained for compatibility with files already
|
|
13
|
+
* written; not the SDK/chain maximum of 7,884,000 or a requirement of Rabdi.
|
|
14
|
+
* EXPIRATION_INCLUSION_MARGIN_BLOCKS retains its legacy public name only. */
|
|
12
15
|
export { MAX_EXPIRATION_BLOCKS, RABDI_MAX_LIFETIME_BLOCKS, EXPIRATION_INCLUSION_MARGIN_BLOCKS } from 'arkiv-chunking';
|
|
13
16
|
export const INLINE_MAX_BYTES = 120_000;
|
|
14
17
|
export const MAX_IMAGE_BYTES = 25 * 1024 * 1024;
|
|
@@ -167,7 +170,7 @@ async function executeStoreImage(options, submitted, observed) {
|
|
|
167
170
|
filenameValid(filename);
|
|
168
171
|
const info = inspectImage(options.bytes, options.contentType), plan = planImage(info.byteLength);
|
|
169
172
|
if (!Number.isSafeInteger(expirationBlocks) || expirationBlocks < Math.max(64, plan.transactionCount + 32) || expirationBlocks > MAX_EXPIRATION_BLOCKS)
|
|
170
|
-
fail('INVALID_INPUT', `Choose a whole-block expiration from max(64, transactionCount + 32) to ${MAX_EXPIRATION_BLOCKS}. Longer storage needs coordinated Lifetime Extension outside this API.`);
|
|
173
|
+
fail('INVALID_INPUT', `Choose a whole-block expiration from max(64, transactionCount + 32) to ${MAX_EXPIRATION_BLOCKS}. The upper bound is this package's file admission limit, kept for compatibility with files already written; it is not the SDK or chain maximum of 7,884,000 blocks or a requirement of Rabdi. Longer storage needs coordinated Lifetime Extension outside this API.`);
|
|
171
174
|
const bytes = new Uint8Array(options.bytes);
|
|
172
175
|
let manifestKey;
|
|
173
176
|
let imageKey;
|
package/docs/verification.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Verify arkiv-images 1.0.
|
|
1
|
+
# Verify arkiv-images 1.0.5
|
|
2
|
+
|
|
3
|
+
Current integration: SDK `^1.0.0`, verified with 1.0.1; exact development, consumer and sample SDK pin 1.0.1.
|
|
2
4
|
|
|
3
5
|
Use Node 22.10+ on the DGX. From this checkout run `npm ci --no-audit --no-fund`, then `node scripts/verify-candidate.mjs`. The script reads package.json, runs library gates, packs that exact version, installs it in a private clean consumer, checks runtime VERSION and public TypeScript imports, and builds an isolated copy of the sample using the same archive. It preserves the sample registry pin and lockfile.
|
|
4
6
|
|
|
@@ -6,7 +8,7 @@ To check a registry installation of the same version, run `node scripts/verify-c
|
|
|
6
8
|
|
|
7
9
|
The public example selects the longer-lived inline JPEG `0x2989bda8bbadfe7e22a0b1e3a435aa3b266106adbbca3f97c162ee4eccca8488` and filters entries using the current block. The short-lived PNG and chunked examples in the old measurements have expired; those measurements are not an availability promise.
|
|
8
10
|
|
|
9
|
-
> Historical 1.0.0 measurements and procedure below are preserved from 51f4905; use the current procedure above for 1.0.
|
|
11
|
+
> Historical 1.0.0 measurements and procedure below are preserved from 51f4905; use the current procedure above for 1.0.5.
|
|
10
12
|
|
|
11
13
|
# Rabdi release verification
|
|
12
14
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arkiv-images",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Store public PNG and JPEG images as Arkiv entities and retrieve verified original bytes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -38,17 +38,19 @@
|
|
|
38
38
|
"lint": "node scripts/lint.mjs",
|
|
39
39
|
"test": "npm run build && node --test test/*.test.mjs",
|
|
40
40
|
"test:browser": "node test/browser-smoke.mjs",
|
|
41
|
-
"prepack": "npm run build"
|
|
41
|
+
"prepack": "npm run build",
|
|
42
|
+
"guard:sdk": "node scripts/sdk-guidance-guard.mjs",
|
|
43
|
+
"guard:vocabulary": "node scripts/vocabulary-guard.mjs"
|
|
42
44
|
},
|
|
43
45
|
"dependencies": {
|
|
44
|
-
"arkiv-chunking": "1.1.
|
|
46
|
+
"arkiv-chunking": "1.1.4"
|
|
45
47
|
},
|
|
46
48
|
"peerDependencies": {
|
|
47
49
|
"@arkiv-network/sdk": "^1.0.0",
|
|
48
50
|
"viem": "^2.56.3"
|
|
49
51
|
},
|
|
50
52
|
"devDependencies": {
|
|
51
|
-
"@arkiv-network/sdk": "1.0.
|
|
53
|
+
"@arkiv-network/sdk": "1.0.1",
|
|
52
54
|
"@types/node": "22.19.13",
|
|
53
55
|
"playwright": "1.62.1",
|
|
54
56
|
"typescript": "5.9.3",
|
package/sample/AGENTS.md
CHANGED
|
@@ -4,7 +4,7 @@ Edit instructions only in AGENTS.md; CLAUDE.md only imports this file.
|
|
|
4
4
|
|
|
5
5
|
Read README.md here and the package README/AGENTS.md before changing the sample. Preserve its existing visual design and English Arkiv copy.
|
|
6
6
|
|
|
7
|
-
- Run `npm ci` in sample; it pins the registry release arkiv-images 1.0.
|
|
7
|
+
- Run `npm ci` in sample; it pins the registry release arkiv-images 1.0.4, SDK `^1.0.0`, verified with 1.0.1 and direct chunking 1.1.4. The published image version retains its own nested chunking 1.1.3; the root image library 1.0.5 uses chunking 1.1.4. Never import sibling source or duplicate package storage, chunking or transaction policy.
|
|
8
8
|
- Retrieval is read-only through /api/rpc. Set ARKIV_ACCESS_KEY server-side only; no browser access key, arbitrary RPC destination, signing method, batch request, historical-state query or raw provider error may pass the proxy.
|
|
9
9
|
- Browser writes use MetaMask/Rabby and the visitor's account/Rabdi RPC. Ask the visitor to configure their own key in their wallet if Rabdi is missing. Never request a private key or add a server signer. Guard account/network before each signature; never switch halfway through a write.
|
|
10
10
|
- Keep the selected file's createImageWriteOperation across clicks/re-renders, including failed or uncertain results. Setup runs after its sending guard is stored. Only an explicit new file choice creates another upload operation. Preserve submitted hashes before receipt rechecks; only an authoritative gas-exhausted revert permits the shared policy's one bounded retry.
|
package/sample/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Image sample — Rabdi
|
|
2
2
|
|
|
3
|
-
This sample uses the registry release **arkiv-images 1.0.
|
|
3
|
+
This sample uses the registry release **arkiv-images 1.0.4** and keeps the image picker, local-date Entity Expiration, byte verification, download, entity inspector, dark/light themes and wallet selection. All copy is English. It targets the existing **arkiv-images-example** Vercel project at https://arkiv-images-example.vercel.app.
|
|
4
4
|
|
|
5
5
|
The UI uses the package public API. Reads go through its own bounded `/api/rpc` function with server-only `ARKIV_ACCESS_KEY`. Only chain ID, current block number, block timing and bounded image/chunk queries are accepted; no signer, access key, upstream URL or raw provider error is sent to the browser. Root and manifest reads are latest state; chunks use keyset pages. Set a free [Hub access key](https://hub.arkiv.network/access-keys) in the Vercel preview environment.
|
|
6
6
|
|
|
@@ -17,7 +17,9 @@ npm ci
|
|
|
17
17
|
npm run build
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
The
|
|
20
|
+
The date input uses this package's 7,883,970-block file admission limit, kept for compatibility with files already written. It is not the SDK or chain maximum of 7,884,000 blocks and is not a requirement of Rabdi. A shared absolute deadline does not require subtracting 30 blocks; standalone SDK 1.0.1+ maximum lifetimes use `ExpirationTime.max()` without subtraction.
|
|
21
|
+
|
|
22
|
+
The sample pins `arkiv-images` to exact registry version `1.0.4`; its lock verifies the published archive integrity. Its direct chunking dependency is pinned to registry version 1.1.4. Published `arkiv-images@1.0.4` also installs its own nested `arkiv-chunking@1.1.3`; the root library version 1.0.5 uses chunking 1.1.4. No local tarball is used or uploaded.
|
|
21
23
|
|
|
22
24
|
## Deploy to the existing project
|
|
23
25
|
|
|
@@ -30,7 +32,7 @@ vercel deploy --cwd sample --prod --scope santiago-hobby
|
|
|
30
32
|
|
|
31
33
|
Vercel builds remotely from the uploaded sample source. Its `vercel.json` selects Vite, runs `npm ci` and `npm run build`, and serves `dist/` together with the Node function `api/rpc.mjs`. This route does not use `--prebuilt` or upload a local `.vercel/output`. The anchored `.vercelignore` allowlist includes the manifest, genuine lock, TypeScript config, HTML, Vercel config, `src/**`, `public/**` and `api/**`; it excludes local environment files and dependency/build directories.
|
|
32
34
|
|
|
33
|
-
Configure `ARKIV_ACCESS_KEY` only in this existing project's server environment, using the sample read key. It is read by `api/rpc.mjs`; Vite receives no access key. Versioned [package documentation](https://github.com/SantiagoDevRel/arkiv-images/tree/v1.0.
|
|
35
|
+
Configure `ARKIV_ACCESS_KEY` only in this existing project's server environment, using the sample read key. It is read by `api/rpc.mjs`; Vite receives no access key. Versioned [package documentation](https://github.com/SantiagoDevRel/arkiv-images/tree/v1.0.4#readme) and the [package agent guide](https://github.com/SantiagoDevRel/arkiv-images/blob/v1.0.4/AGENTS.md) match the installed release. `node scripts/sample-release-guard.mjs` from the repository root checks versioned sample links and the remote-build upload contract; `npm test` executes its negative mutations.
|
|
34
36
|
|
|
35
37
|
The Vite development server alone does not serve Vercel functions. Use a Vercel preview for the complete real-network read flow; controlled browser tests route `/api/rpc` to the in-memory harness. Never put an access key in Vite environment variables.
|
|
36
38
|
|