@jolly-pixel/asset-server 1.0.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/LICENSE +21 -0
- package/README.md +83 -0
- package/dist/catalog/CatalogExtension.d.ts +37 -0
- package/dist/catalog/CatalogExtension.d.ts.map +1 -0
- package/dist/catalog/CatalogExtension.js +82 -0
- package/dist/catalog/CatalogIdentitySidecar.d.ts +52 -0
- package/dist/catalog/CatalogIdentitySidecar.d.ts.map +1 -0
- package/dist/catalog/CatalogIdentitySidecar.js +132 -0
- package/dist/catalog/CatalogProjection.d.ts +32 -0
- package/dist/catalog/CatalogProjection.d.ts.map +1 -0
- package/dist/catalog/CatalogProjection.js +109 -0
- package/dist/catalog/httpHandler.d.ts +13 -0
- package/dist/catalog/httpHandler.d.ts.map +1 -0
- package/dist/catalog/httpHandler.js +27 -0
- package/dist/catalog/index.d.ts +9 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +4 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +13 -0
- package/dist/createAssetBackend.d.ts +79 -0
- package/dist/createAssetBackend.d.ts.map +1 -0
- package/dist/createAssetBackend.js +146 -0
- package/dist/events/AssetEvents.d.ts +54 -0
- package/dist/events/AssetEvents.d.ts.map +1 -0
- package/dist/events/AssetEvents.js +102 -0
- package/dist/events/AssetEvents.schema.d.ts +111 -0
- package/dist/events/AssetEvents.schema.d.ts.map +1 -0
- package/dist/events/AssetEvents.schema.js +75 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/kinds/AssetKindHandler.d.ts +38 -0
- package/dist/kinds/AssetKindHandler.d.ts.map +1 -0
- package/dist/kinds/AssetKindHandler.js +1 -0
- package/dist/kinds/AssetKindRegistry.d.ts +14 -0
- package/dist/kinds/AssetKindRegistry.d.ts.map +1 -0
- package/dist/kinds/AssetKindRegistry.js +52 -0
- package/dist/kinds/errors/UnknownAssetKindError.d.ts +5 -0
- package/dist/kinds/errors/UnknownAssetKindError.d.ts.map +1 -0
- package/dist/kinds/errors/UnknownAssetKindError.js +8 -0
- package/dist/kinds/errors/index.d.ts +2 -0
- package/dist/kinds/errors/index.d.ts.map +1 -0
- package/dist/kinds/errors/index.js +1 -0
- package/dist/kinds/handlers/binary.d.ts +10 -0
- package/dist/kinds/handlers/binary.d.ts.map +1 -0
- package/dist/kinds/handlers/binary.js +31 -0
- package/dist/kinds/handlers/index.d.ts +5 -0
- package/dist/kinds/handlers/index.d.ts.map +1 -0
- package/dist/kinds/handlers/index.js +2 -0
- package/dist/kinds/handlers/texture.d.ts +12 -0
- package/dist/kinds/handlers/texture.d.ts.map +1 -0
- package/dist/kinds/handlers/texture.js +27 -0
- package/dist/kinds/index.d.ts +5 -0
- package/dist/kinds/index.d.ts.map +1 -0
- package/dist/kinds/index.js +3 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +9 -0
- package/dist/plugins/vite.d.ts +36 -0
- package/dist/plugins/vite.d.ts.map +1 -0
- package/dist/plugins/vite.js +60 -0
- package/dist/rooms/AssetRoomExtension.d.ts +29 -0
- package/dist/rooms/AssetRoomExtension.d.ts.map +1 -0
- package/dist/rooms/AssetRoomExtension.js +50 -0
- package/dist/rooms/index.d.ts +5 -0
- package/dist/rooms/index.d.ts.map +1 -0
- package/dist/rooms/index.js +2 -0
- package/dist/rooms/registerAssetRooms.d.ts +21 -0
- package/dist/rooms/registerAssetRooms.d.ts.map +1 -0
- package/dist/rooms/registerAssetRooms.js +71 -0
- package/dist/static/contentTypes.d.ts +6 -0
- package/dist/static/contentTypes.d.ts.map +1 -0
- package/dist/static/contentTypes.js +27 -0
- package/dist/static/httpHandler.d.ts +24 -0
- package/dist/static/httpHandler.d.ts.map +1 -0
- package/dist/static/httpHandler.js +105 -0
- package/dist/static/index.d.ts +4 -0
- package/dist/static/index.d.ts.map +1 -0
- package/dist/static/index.js +2 -0
- package/dist/sync/AssetProjector.d.ts +33 -0
- package/dist/sync/AssetProjector.d.ts.map +1 -0
- package/dist/sync/AssetProjector.js +186 -0
- package/dist/sync/AssetStateStore.d.ts +28 -0
- package/dist/sync/AssetStateStore.d.ts.map +1 -0
- package/dist/sync/AssetStateStore.js +86 -0
- package/dist/sync/AssetWriter.d.ts +54 -0
- package/dist/sync/AssetWriter.d.ts.map +1 -0
- package/dist/sync/AssetWriter.js +149 -0
- package/dist/sync/ProjectionState.d.ts +33 -0
- package/dist/sync/ProjectionState.d.ts.map +1 -0
- package/dist/sync/ProjectionState.js +129 -0
- package/dist/sync/Reconciler.d.ts +36 -0
- package/dist/sync/Reconciler.d.ts.map +1 -0
- package/dist/sync/Reconciler.js +182 -0
- package/dist/sync/ReconciliationWatcher.d.ts +28 -0
- package/dist/sync/ReconciliationWatcher.d.ts.map +1 -0
- package/dist/sync/ReconciliationWatcher.js +86 -0
- package/dist/sync/SnapshotScheduler.d.ts +29 -0
- package/dist/sync/SnapshotScheduler.d.ts.map +1 -0
- package/dist/sync/SnapshotScheduler.js +136 -0
- package/dist/sync/foldProjection.d.ts +12 -0
- package/dist/sync/foldProjection.d.ts.map +1 -0
- package/dist/sync/foldProjection.js +32 -0
- package/dist/sync/index.d.ts +19 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +9 -0
- package/dist/sync/matchRenames.d.ts +45 -0
- package/dist/sync/matchRenames.d.ts.map +1 -0
- package/dist/sync/matchRenames.js +85 -0
- package/dist/utils/TaskChain.d.ts +9 -0
- package/dist/utils/TaskChain.d.ts.map +1 -0
- package/dist/utils/TaskChain.js +14 -0
- package/dist/utils/contentHash.d.ts +2 -0
- package/dist/utils/contentHash.d.ts.map +1 -0
- package/dist/utils/contentHash.js +7 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/workspace/createAssetWorkspace.d.ts +71 -0
- package/dist/workspace/createAssetWorkspace.d.ts.map +1 -0
- package/dist/workspace/createAssetWorkspace.js +72 -0
- package/dist/workspace/index.d.ts +5 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +2 -0
- package/dist/workspace/seedAssetSource.d.ts +5 -0
- package/dist/workspace/seedAssetSource.d.ts.map +1 -0
- package/dist/workspace/seedAssetSource.js +20 -0
- package/docs/AssetBackend.md +73 -0
- package/docs/AssetKinds.md +204 -0
- package/docs/AssetWriter.md +62 -0
- package/docs/Catalog.md +71 -0
- package/docs/Rooms.md +70 -0
- package/docs/Sync.md +146 -0
- package/docs/Workspace.md +172 -0
- package/package.json +83 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 JollyPixel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
asset-server
|
|
3
|
+
</h1>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
Server-side asset storage, synchronization and catalog delivery
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
## 💃 Getting Started
|
|
10
|
+
|
|
11
|
+
Install the package with npm:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
$ npm i @jolly-pixel/asset-server
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`@jolly-pixel/asset-server` runs on the server. Browser code should use
|
|
18
|
+
[`@jolly-pixel/asset`](../asset) for asset records and catalogs.
|
|
19
|
+
Physical storage providers are supplied by
|
|
20
|
+
[`@jolly-pixel/asset-source`](../asset-source).
|
|
21
|
+
|
|
22
|
+
## 👀 Usage example
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import * as EventStore from "@jolly-pixel/event-store";
|
|
26
|
+
import { FilesystemAssetSource } from "@jolly-pixel/asset-source";
|
|
27
|
+
import { Server } from "@jolly-pixel/network";
|
|
28
|
+
import {
|
|
29
|
+
createAssetBackend,
|
|
30
|
+
textureAssetHandler
|
|
31
|
+
} from "@jolly-pixel/asset-server";
|
|
32
|
+
|
|
33
|
+
using eventStore = await EventStore.persistence.sqlite(
|
|
34
|
+
"./assets/.jollypixel/events.db"
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
await using backend = await createAssetBackend({
|
|
38
|
+
source: new FilesystemAssetSource("./assets"),
|
|
39
|
+
eventStore,
|
|
40
|
+
handlers: [textureAssetHandler()]
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await using server = new Server({ eventStore });
|
|
44
|
+
backend.attach(server);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
On startup, the backend catalogs files already present in `./assets`. Changes
|
|
48
|
+
made through `backend.writer` are appended to the event store and written to
|
|
49
|
+
the asset source. Changes made by external tools are detected and appended as
|
|
50
|
+
system events.
|
|
51
|
+
|
|
52
|
+
## 📚 API
|
|
53
|
+
|
|
54
|
+
- [`AssetBackend`](./docs/AssetBackend.md): setup, options and lifecycle
|
|
55
|
+
- [`AssetWriter`](./docs/AssetWriter.md): create, update, rename and remove assets
|
|
56
|
+
- [`AssetSource`](../asset-source/docs/AssetSource.md): in-memory and
|
|
57
|
+
filesystem storage
|
|
58
|
+
- [`Asset kinds`](./docs/AssetKinds.md): custom state, serialization and editing rooms
|
|
59
|
+
- [`Catalog`](./docs/Catalog.md): catalog projection, network messages and HTTP access
|
|
60
|
+
- [`Rooms`](./docs/Rooms.md): dynamic editing rooms and eviction
|
|
61
|
+
- [`Sync`](./docs/Sync.md): lifecycle events, snapshots and reconciliation
|
|
62
|
+
|
|
63
|
+
## ✨ Contributors guide
|
|
64
|
+
|
|
65
|
+
Read the [contributing guide][contributing] before submitting a change.
|
|
66
|
+
|
|
67
|
+
Run these commands from the monorepo root:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
$ npm run test -w @jolly-pixel/asset-server
|
|
71
|
+
$ npm run lint
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> [!CAUTION]
|
|
75
|
+
> Include tests when adding a feature or fixing a bug.
|
|
76
|
+
|
|
77
|
+
## 📃 License
|
|
78
|
+
|
|
79
|
+
MIT
|
|
80
|
+
|
|
81
|
+
<!-- Reference-style links -->
|
|
82
|
+
|
|
83
|
+
[contributing]: ../../CONTRIBUTING.md
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Extension, type ClientHandle, type MessageProtocols, type PeerMetadata, type RoomContext } from "@jolly-pixel/network";
|
|
2
|
+
import type { AssetManifestData } from "@jolly-pixel/asset";
|
|
3
|
+
import type { CatalogChange, CatalogProjection } from "./CatalogProjection.ts";
|
|
4
|
+
export declare const CATALOG_ROOM = "asset-catalog";
|
|
5
|
+
export declare const CATALOG_SNAPSHOT = "catalog:snapshot";
|
|
6
|
+
export declare const CATALOG_CHANGED = "catalog:changed";
|
|
7
|
+
export type CatalogMessage = {
|
|
8
|
+
type: typeof CATALOG_SNAPSHOT;
|
|
9
|
+
manifest: AssetManifestData;
|
|
10
|
+
} | {
|
|
11
|
+
type: typeof CATALOG_CHANGED;
|
|
12
|
+
change: CatalogChange;
|
|
13
|
+
};
|
|
14
|
+
export declare const catalogProtocols: MessageProtocols;
|
|
15
|
+
export interface CatalogExtensionOptions {
|
|
16
|
+
projection: CatalogProjection;
|
|
17
|
+
/**
|
|
18
|
+
* Room name clients join to follow the catalog.
|
|
19
|
+
* @default CATALOG_ROOM
|
|
20
|
+
*/
|
|
21
|
+
id?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Broadcasts the projected catalog without owning domain state.
|
|
25
|
+
*/
|
|
26
|
+
export declare class CatalogExtension extends Extension {
|
|
27
|
+
#private;
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly name = "asset-catalog";
|
|
30
|
+
readonly protocols: MessageProtocols;
|
|
31
|
+
constructor(options: CatalogExtensionOptions);
|
|
32
|
+
onClientConnect(client: ClientHandle, _identity: PeerMetadata, context: RoomContext): void;
|
|
33
|
+
onClientDisconnect(clientId: string): void;
|
|
34
|
+
onMessage(): void;
|
|
35
|
+
dispose(): void;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=CatalogExtension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CatalogExtension.d.ts","sourceRoot":"","sources":["../../src/catalog/CatalogExtension.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,SAAS,EAET,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAEjB,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,OAAO,gBAAgB,CAAC;IAAC,QAAQ,EAAE,iBAAiB,CAAC;CAAE,GAC/D;IAAE,IAAI,EAAE,OAAO,eAAe,CAAC;IAAC,MAAM,EAAE,aAAa,CAAC;CAAE,CAAC;AAE7D,eAAO,MAAM,gBAAgB,EAAE,gBA+B9B,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,iBAAiB,CAAC;IAC9B;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,SAAS;;IAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,mBAAgB;IAC7B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAoB;gBAQtD,OAAO,EAAE,uBAAuB;IAelC,eAAe,CACb,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,WAAW,GACnB,IAAI;IAUP,kBAAkB,CAChB,QAAQ,EAAE,MAAM,GACf,IAAI;IAOP,SAAS,IAAI,IAAI;IAIR,OAAO,IAAI,IAAI;CAQzB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import { defineMessageProtocol, Extension, NO_MESSAGES } from "@jolly-pixel/network";
|
|
3
|
+
// CONSTANTS
|
|
4
|
+
export const CATALOG_ROOM = "asset-catalog";
|
|
5
|
+
export const CATALOG_SNAPSHOT = "catalog:snapshot";
|
|
6
|
+
export const CATALOG_CHANGED = "catalog:changed";
|
|
7
|
+
export const catalogProtocols = {
|
|
8
|
+
inbound: NO_MESSAGES,
|
|
9
|
+
outbound: defineMessageProtocol({
|
|
10
|
+
discriminator: "type",
|
|
11
|
+
schema: {
|
|
12
|
+
oneOf: [
|
|
13
|
+
{
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {
|
|
16
|
+
type: { const: CATALOG_SNAPSHOT },
|
|
17
|
+
manifest: { type: "object" }
|
|
18
|
+
},
|
|
19
|
+
required: [
|
|
20
|
+
"type",
|
|
21
|
+
"manifest"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: "object",
|
|
26
|
+
properties: {
|
|
27
|
+
type: { const: CATALOG_CHANGED },
|
|
28
|
+
change: { type: "object" }
|
|
29
|
+
},
|
|
30
|
+
required: [
|
|
31
|
+
"type",
|
|
32
|
+
"change"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Broadcasts the projected catalog without owning domain state.
|
|
41
|
+
*/
|
|
42
|
+
export class CatalogExtension extends Extension {
|
|
43
|
+
id;
|
|
44
|
+
name = CATALOG_ROOM;
|
|
45
|
+
protocols = catalogProtocols;
|
|
46
|
+
#projection;
|
|
47
|
+
#broadcast = null;
|
|
48
|
+
#members = new Set();
|
|
49
|
+
#onChanged;
|
|
50
|
+
constructor(options) {
|
|
51
|
+
super();
|
|
52
|
+
this.id = options.id ?? CATALOG_ROOM;
|
|
53
|
+
this.#projection = options.projection;
|
|
54
|
+
this.#onChanged = (change) => this.#broadcast?.broadcast({
|
|
55
|
+
type: CATALOG_CHANGED,
|
|
56
|
+
change
|
|
57
|
+
});
|
|
58
|
+
this.#projection.on("changed", this.#onChanged);
|
|
59
|
+
}
|
|
60
|
+
onClientConnect(client, _identity, context) {
|
|
61
|
+
this.#broadcast = context.room;
|
|
62
|
+
this.#members.add(client.id);
|
|
63
|
+
context.room.sendTo(client.id, {
|
|
64
|
+
type: CATALOG_SNAPSHOT,
|
|
65
|
+
manifest: this.#projection.snapshot()
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
onClientDisconnect(clientId) {
|
|
69
|
+
this.#members.delete(clientId);
|
|
70
|
+
if (this.#members.size === 0) {
|
|
71
|
+
this.#broadcast = null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
onMessage() {
|
|
75
|
+
return void 0;
|
|
76
|
+
}
|
|
77
|
+
dispose() {
|
|
78
|
+
this.#projection.off("changed", this.#onChanged);
|
|
79
|
+
this.#members.clear();
|
|
80
|
+
this.#broadcast = null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type Infer } from "ata-validator";
|
|
2
|
+
import { type AssetSource } from "@jolly-pixel/asset-source";
|
|
3
|
+
import { type Logger } from "../logger.ts";
|
|
4
|
+
declare const kEntrySchema: {
|
|
5
|
+
readonly type: "object";
|
|
6
|
+
readonly properties: {
|
|
7
|
+
readonly id: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
};
|
|
10
|
+
readonly path: {
|
|
11
|
+
readonly type: "string";
|
|
12
|
+
};
|
|
13
|
+
readonly kind: {
|
|
14
|
+
readonly type: "string";
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
readonly required: readonly ["id", "path", "kind"];
|
|
18
|
+
};
|
|
19
|
+
export type IdentityEntry = Readonly<Infer<typeof kEntrySchema>>;
|
|
20
|
+
export interface CatalogIdentitySidecarParse {
|
|
21
|
+
readonly sidecar: CatalogIdentitySidecar;
|
|
22
|
+
readonly dropped: number;
|
|
23
|
+
}
|
|
24
|
+
export interface CatalogIdentitySidecarData {
|
|
25
|
+
readonly version: 1;
|
|
26
|
+
readonly assets: readonly IdentityEntry[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Persists path-to-AssetId mappings beside the workspace.
|
|
30
|
+
*
|
|
31
|
+
* The committed half of the catalog: {@link CatalogProjection} is replayed
|
|
32
|
+
* from the event log and can always be rebuilt, while this file is the only
|
|
33
|
+
* record that survives a clone, since the log itself is never committed.
|
|
34
|
+
*
|
|
35
|
+
* An unreadable sidecar loses ids, not event data.
|
|
36
|
+
*/
|
|
37
|
+
export declare class CatalogIdentitySidecar {
|
|
38
|
+
#private;
|
|
39
|
+
constructor(entries?: Iterable<IdentityEntry>);
|
|
40
|
+
get size(): number;
|
|
41
|
+
set(entry: IdentityEntry): this;
|
|
42
|
+
removeById(id: string): boolean;
|
|
43
|
+
byPath(path: string): IdentityEntry | undefined;
|
|
44
|
+
byId(id: string): IdentityEntry | undefined;
|
|
45
|
+
[Symbol.iterator](): IterableIterator<IdentityEntry>;
|
|
46
|
+
toJSON(): CatalogIdentitySidecarData;
|
|
47
|
+
save(source: AssetSource): Promise<void>;
|
|
48
|
+
static load(source: AssetSource, logger?: Logger): Promise<CatalogIdentitySidecar>;
|
|
49
|
+
static parse(input: unknown): CatalogIdentitySidecarParse;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=CatalogIdentitySidecar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CatalogIdentitySidecar.d.ts","sourceRoot":"","sources":["../../src/catalog/CatalogIdentitySidecar.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,KAAK,EACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAEL,KAAK,MAAM,EACZ,MAAM,cAAc,CAAC;AAMtB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;CAYhB,CAAC;AAaH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC;AAEjE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C;AAED;;;;;;;;GAQG;AACH,qBAAa,sBAAsB;;gBAK/B,OAAO,GAAE,QAAQ,CAAC,aAAa,CAAM;IAOvC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,GAAG,CACD,KAAK,EAAE,aAAa,GACnB,IAAI;IAsBP,UAAU,CACR,EAAE,EAAE,MAAM,GACT,OAAO;IAYV,MAAM,CACJ,IAAI,EAAE,MAAM,GACX,aAAa,GAAG,SAAS;IAI5B,IAAI,CACF,EAAE,EAAE,MAAM,GACT,aAAa,GAAG,SAAS;IAI5B,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,aAAa,CAAC;IAIpD,MAAM,IAAI,0BAA0B;IASpC,IAAI,CACF,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,IAAI,CAAC;WAQH,IAAI,CACf,MAAM,EAAE,WAAW,EACnB,MAAM,GAAE,MAAuB,GAC9B,OAAO,CAAC,sBAAsB,CAAC;IAmBlC,MAAM,CAAC,KAAK,CACV,KAAK,EAAE,OAAO,GACb,2BAA2B;CA2B/B"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import { defineSchema, Validator } from "ata-validator";
|
|
3
|
+
import { readJsonFile, writeJsonFile } from "@jolly-pixel/asset-source";
|
|
4
|
+
// Import Internal Dependencies
|
|
5
|
+
import { silentLogger } from "../logger.js";
|
|
6
|
+
import { IDENTITY_SIDECAR_PATH } from "../constants.js";
|
|
7
|
+
// CONSTANTS
|
|
8
|
+
const kSidecarVersion = 1;
|
|
9
|
+
const kValidatorOptions = { useDefaults: false };
|
|
10
|
+
const kEntrySchema = defineSchema({
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
id: { type: "string" },
|
|
14
|
+
path: { type: "string" },
|
|
15
|
+
kind: { type: "string" }
|
|
16
|
+
},
|
|
17
|
+
required: [
|
|
18
|
+
"id",
|
|
19
|
+
"path",
|
|
20
|
+
"kind"
|
|
21
|
+
]
|
|
22
|
+
});
|
|
23
|
+
const kEntryValidator = new Validator(kEntrySchema, kValidatorOptions);
|
|
24
|
+
const kDocumentValidator = new Validator(defineSchema({
|
|
25
|
+
type: "object",
|
|
26
|
+
properties: {
|
|
27
|
+
assets: { type: "array" }
|
|
28
|
+
},
|
|
29
|
+
required: ["assets"]
|
|
30
|
+
}), kValidatorOptions);
|
|
31
|
+
/**
|
|
32
|
+
* Persists path-to-AssetId mappings beside the workspace.
|
|
33
|
+
*
|
|
34
|
+
* The committed half of the catalog: {@link CatalogProjection} is replayed
|
|
35
|
+
* from the event log and can always be rebuilt, while this file is the only
|
|
36
|
+
* record that survives a clone, since the log itself is never committed.
|
|
37
|
+
*
|
|
38
|
+
* An unreadable sidecar loses ids, not event data.
|
|
39
|
+
*/
|
|
40
|
+
export class CatalogIdentitySidecar {
|
|
41
|
+
#byPath = new Map();
|
|
42
|
+
#byId = new Map();
|
|
43
|
+
constructor(entries = []) {
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
this.set(entry);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
get size() {
|
|
49
|
+
return this.#byPath.size;
|
|
50
|
+
}
|
|
51
|
+
set(entry) {
|
|
52
|
+
const previousPath = this.#byId.get(entry.id);
|
|
53
|
+
if (previousPath !== undefined) {
|
|
54
|
+
this.#byPath.delete(previousPath.path);
|
|
55
|
+
}
|
|
56
|
+
const previousId = this.#byPath.get(entry.path);
|
|
57
|
+
if (previousId !== undefined) {
|
|
58
|
+
this.#byId.delete(previousId.id);
|
|
59
|
+
}
|
|
60
|
+
const stored = {
|
|
61
|
+
id: entry.id,
|
|
62
|
+
path: entry.path,
|
|
63
|
+
kind: entry.kind
|
|
64
|
+
};
|
|
65
|
+
this.#byPath.set(stored.path, stored);
|
|
66
|
+
this.#byId.set(stored.id, stored);
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
removeById(id) {
|
|
70
|
+
const entry = this.#byId.get(id);
|
|
71
|
+
if (entry === undefined) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
this.#byId.delete(id);
|
|
75
|
+
this.#byPath.delete(entry.path);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
byPath(path) {
|
|
79
|
+
return this.#byPath.get(path);
|
|
80
|
+
}
|
|
81
|
+
byId(id) {
|
|
82
|
+
return this.#byId.get(id);
|
|
83
|
+
}
|
|
84
|
+
[Symbol.iterator]() {
|
|
85
|
+
return this.#byId.values();
|
|
86
|
+
}
|
|
87
|
+
toJSON() {
|
|
88
|
+
return {
|
|
89
|
+
version: kSidecarVersion,
|
|
90
|
+
assets: [...this.#byId.values()].sort((a, b) => a.path.localeCompare(b.path))
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
save(source) {
|
|
94
|
+
return writeJsonFile(source, IDENTITY_SIDECAR_PATH, this.toJSON());
|
|
95
|
+
}
|
|
96
|
+
static async load(source, logger = silentLogger()) {
|
|
97
|
+
const { sidecar, dropped } = CatalogIdentitySidecar.parse(await readJsonFile(source, IDENTITY_SIDECAR_PATH));
|
|
98
|
+
if (dropped > 0) {
|
|
99
|
+
logger
|
|
100
|
+
.withMetadata({
|
|
101
|
+
path: IDENTITY_SIDECAR_PATH,
|
|
102
|
+
dropped
|
|
103
|
+
})
|
|
104
|
+
.warn("identity sidecar entries dropped");
|
|
105
|
+
}
|
|
106
|
+
return sidecar;
|
|
107
|
+
}
|
|
108
|
+
static parse(input) {
|
|
109
|
+
const document = kDocumentValidator.validate(input);
|
|
110
|
+
if (!document.valid) {
|
|
111
|
+
return {
|
|
112
|
+
sidecar: new CatalogIdentitySidecar(),
|
|
113
|
+
dropped: 0
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const entries = [];
|
|
117
|
+
let dropped = 0;
|
|
118
|
+
for (const asset of document.data.assets) {
|
|
119
|
+
const entry = kEntryValidator.validate(asset);
|
|
120
|
+
if (entry.valid) {
|
|
121
|
+
entries.push(entry.data);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
dropped += 1;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
sidecar: new CatalogIdentitySidecar(entries),
|
|
129
|
+
dropped
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type * as EventStore from "@jolly-pixel/event-store";
|
|
2
|
+
import { AssetCatalog, type AssetManifestData, type AssetRecordData } from "@jolly-pixel/asset";
|
|
3
|
+
import { Emitter } from "@openally/emitt";
|
|
4
|
+
export interface CatalogChange {
|
|
5
|
+
readonly eventType: string;
|
|
6
|
+
readonly assetId: string;
|
|
7
|
+
/**
|
|
8
|
+
* The record after the change, or `null` when the asset was removed.
|
|
9
|
+
*/
|
|
10
|
+
readonly record: AssetRecordData | null;
|
|
11
|
+
}
|
|
12
|
+
export type CatalogProjectionEventMap = {
|
|
13
|
+
changed: (change: CatalogChange) => void;
|
|
14
|
+
};
|
|
15
|
+
export interface CatalogProjectionOptions {
|
|
16
|
+
eventStore: EventStore.EventStore;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Projects lifecycle events into catalog records keyed by asset id.
|
|
20
|
+
*/
|
|
21
|
+
export declare class CatalogProjection extends Emitter<CatalogProjectionEventMap> {
|
|
22
|
+
#private;
|
|
23
|
+
constructor(options: CatalogProjectionOptions);
|
|
24
|
+
get catalog(): AssetCatalog;
|
|
25
|
+
get size(): number;
|
|
26
|
+
load(): void;
|
|
27
|
+
start(): void;
|
|
28
|
+
close(): void;
|
|
29
|
+
apply(event: EventStore.Event): boolean;
|
|
30
|
+
snapshot(): AssetManifestData;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=CatalogProjection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CatalogProjection.d.ts","sourceRoot":"","sources":["../../src/catalog/CatalogProjection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,UAAU,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EACL,YAAY,EAGZ,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAc1C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,CACP,MAAM,EAAE,aAAa,KAClB,IAAI,CAAC;CACX,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC;CACnC;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,OAAO,CAC5C,yBAAyB,CAC1B;;gBAMG,OAAO,EAAE,wBAAwB;IAMnC,IAAI,OAAO,IAAI,YAAY,CAE1B;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,IAAI;IAWZ,KAAK,IAAI,IAAI;IAOb,KAAK,IAAI,IAAI;IAMb,KAAK,CACH,KAAK,EAAE,UAAU,CAAC,KAAK,GACtB,OAAO;IAgBV,QAAQ,IAAI,iBAAiB;CAqE9B"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { AssetCatalog, AssetId, AssetRecord } from "@jolly-pixel/asset";
|
|
2
|
+
import { Emitter } from "@openally/emitt";
|
|
3
|
+
// Import Internal Dependencies
|
|
4
|
+
import { ASSET_EVENT_PREFIX } from "../constants.js";
|
|
5
|
+
import { ASSET_CHECKPOINT_EVENT_TYPES, ASSET_CREATED, ASSET_DELETED, ASSET_RENAMED, ASSET_UPDATED, parseAssetEvent } from "../events/AssetEvents.js";
|
|
6
|
+
/**
|
|
7
|
+
* Projects lifecycle events into catalog records keyed by asset id.
|
|
8
|
+
*/
|
|
9
|
+
export class CatalogProjection extends Emitter {
|
|
10
|
+
#eventStore;
|
|
11
|
+
#catalog = new AssetCatalog();
|
|
12
|
+
#unsubscribe = null;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
super();
|
|
15
|
+
this.#eventStore = options.eventStore;
|
|
16
|
+
}
|
|
17
|
+
get catalog() {
|
|
18
|
+
return this.#catalog;
|
|
19
|
+
}
|
|
20
|
+
get size() {
|
|
21
|
+
return this.#catalog.size;
|
|
22
|
+
}
|
|
23
|
+
load() {
|
|
24
|
+
this.#catalog = new AssetCatalog();
|
|
25
|
+
const events = this.#eventStore.reader.listFromCheckpoints({
|
|
26
|
+
checkpointEventTypes: ASSET_CHECKPOINT_EVENT_TYPES,
|
|
27
|
+
eventTypePrefix: ASSET_EVENT_PREFIX
|
|
28
|
+
});
|
|
29
|
+
for (const event of events) {
|
|
30
|
+
this.apply(event);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
start() {
|
|
34
|
+
this.#unsubscribe ??= this.#eventStore.subscribe((event) => void this.apply(event), { eventTypePrefix: ASSET_EVENT_PREFIX });
|
|
35
|
+
}
|
|
36
|
+
close() {
|
|
37
|
+
this.#unsubscribe?.();
|
|
38
|
+
this.#unsubscribe = null;
|
|
39
|
+
this.removeAllListeners();
|
|
40
|
+
}
|
|
41
|
+
apply(event) {
|
|
42
|
+
const parsed = parseAssetEvent(event);
|
|
43
|
+
if (!parsed.ok) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const change = this.#fold(parsed.val);
|
|
47
|
+
if (change === null) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
this.emit("changed", change);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
snapshot() {
|
|
54
|
+
return this.#catalog.toJSON();
|
|
55
|
+
}
|
|
56
|
+
#fold(event) {
|
|
57
|
+
const id = new AssetId(event.assetId);
|
|
58
|
+
switch (event.eventType) {
|
|
59
|
+
case ASSET_CREATED:
|
|
60
|
+
case ASSET_UPDATED: {
|
|
61
|
+
const data = event.eventData;
|
|
62
|
+
return this.#upsert(new AssetRecord({
|
|
63
|
+
id,
|
|
64
|
+
kind: data.kind,
|
|
65
|
+
source: data.path,
|
|
66
|
+
revision: data.hash
|
|
67
|
+
}), event.eventType);
|
|
68
|
+
}
|
|
69
|
+
case ASSET_RENAMED: {
|
|
70
|
+
const data = event.eventData;
|
|
71
|
+
const previous = this.#catalog.has(id) ?
|
|
72
|
+
this.#catalog.get(id) :
|
|
73
|
+
null;
|
|
74
|
+
return this.#upsert(new AssetRecord({
|
|
75
|
+
id,
|
|
76
|
+
kind: previous?.kind ?? data.kind,
|
|
77
|
+
source: data.to,
|
|
78
|
+
revision: previous?.revision ?? data.hash
|
|
79
|
+
}), event.eventType);
|
|
80
|
+
}
|
|
81
|
+
case ASSET_DELETED: {
|
|
82
|
+
if (!this.#catalog.has(id)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
this.#catalog.remove(id);
|
|
86
|
+
return {
|
|
87
|
+
eventType: event.eventType,
|
|
88
|
+
assetId: event.assetId,
|
|
89
|
+
record: null
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
default:
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
#upsert(record, eventType) {
|
|
97
|
+
if (this.#catalog.has(record.id)) {
|
|
98
|
+
this.#catalog.replace(record);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.#catalog.add(record);
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
eventType,
|
|
105
|
+
assetId: record.id.value,
|
|
106
|
+
record: record.toJSON()
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { CatalogProjection } from "./CatalogProjection.ts";
|
|
3
|
+
export declare const DEFAULT_CATALOG_PATH = "/__jollypixel/catalog";
|
|
4
|
+
export type CatalogHandler = (request: IncomingMessage, response: ServerResponse, next: () => void) => void;
|
|
5
|
+
export interface CatalogHandlerOptions {
|
|
6
|
+
projection: CatalogProjection;
|
|
7
|
+
/**
|
|
8
|
+
* @default DEFAULT_CATALOG_PATH
|
|
9
|
+
*/
|
|
10
|
+
path?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function createCatalogHandler(options: CatalogHandlerOptions): CatalogHandler;
|
|
13
|
+
//# sourceMappingURL=httpHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpHandler.d.ts","sourceRoot":"","sources":["../../src/catalog/httpHandler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACf,MAAM,WAAW,CAAC;AAMnB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,eAAO,MAAM,oBAAoB,0BAAmB,CAAC;AAErD,MAAM,MAAM,cAAc,GAAG,CAC3B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,MAAM,IAAI,KACb,IAAI,CAAC;AAEV,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,iBAAiB,CAAC;IAC9B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAC7B,cAAc,CAiDhB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Import Node.js Dependencies
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
3
|
+
// Import Third-party Dependencies
|
|
4
|
+
import { CATALOG_URL_PATH } from "@jolly-pixel/asset";
|
|
5
|
+
export const DEFAULT_CATALOG_PATH = CATALOG_URL_PATH;
|
|
6
|
+
export function createCatalogHandler(options) {
|
|
7
|
+
const { projection, path = DEFAULT_CATALOG_PATH } = options;
|
|
8
|
+
return function catalogHandler(request, response, next) {
|
|
9
|
+
const requestUrl = URL.parse(request.url ?? "", "http://localhost");
|
|
10
|
+
if (requestUrl?.pathname !== path) {
|
|
11
|
+
next();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (request.method !== "GET" &&
|
|
15
|
+
request.method !== "HEAD") {
|
|
16
|
+
response.statusCode = 405;
|
|
17
|
+
response.setHeader("allow", "GET, HEAD");
|
|
18
|
+
response.end();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const payload = JSON.stringify(projection.snapshot());
|
|
22
|
+
response.statusCode = 200;
|
|
23
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
24
|
+
response.setHeader("content-length", String(Buffer.byteLength(payload)));
|
|
25
|
+
response.end(request.method === "HEAD" ? undefined : payload);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { CatalogIdentitySidecar } from "./CatalogIdentitySidecar.ts";
|
|
2
|
+
export type { CatalogIdentitySidecarData, IdentityEntry } from "./CatalogIdentitySidecar.ts";
|
|
3
|
+
export { CatalogProjection } from "./CatalogProjection.ts";
|
|
4
|
+
export type { CatalogChange, CatalogProjectionEventMap, CatalogProjectionOptions } from "./CatalogProjection.ts";
|
|
5
|
+
export { CatalogExtension, CATALOG_CHANGED, CATALOG_ROOM, CATALOG_SNAPSHOT } from "./CatalogExtension.ts";
|
|
6
|
+
export type { CatalogExtensionOptions, CatalogMessage } from "./CatalogExtension.ts";
|
|
7
|
+
export { createCatalogHandler, DEFAULT_CATALOG_PATH } from "./httpHandler.ts";
|
|
8
|
+
export type { CatalogHandler, CatalogHandlerOptions } from "./httpHandler.ts";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/catalog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,YAAY,EACV,0BAA0B,EAC1B,aAAa,EACd,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EACV,aAAa,EACb,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,uBAAuB,EACvB,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,cAAc,EACd,qBAAqB,EACtB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { CatalogIdentitySidecar } from "./CatalogIdentitySidecar.js";
|
|
2
|
+
export { CatalogProjection } from "./CatalogProjection.js";
|
|
3
|
+
export { CatalogExtension, CATALOG_CHANGED, CATALOG_ROOM, CATALOG_SNAPSHOT } from "./CatalogExtension.js";
|
|
4
|
+
export { createCatalogHandler, DEFAULT_CATALOG_PATH } from "./httpHandler.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { STATE_DIRECTORY } from "@jolly-pixel/asset-source";
|
|
2
|
+
export { STATE_DIRECTORY };
|
|
3
|
+
export declare const IDENTITY_SIDECAR_PATH = ".jollypixel/assets.json";
|
|
4
|
+
export declare const PROJECTION_STATE_PATH = ".jollypixel/state.json";
|
|
5
|
+
export declare const STATE_GITIGNORE_PATH = ".jollypixel/.gitignore";
|
|
6
|
+
export declare const EVENTS_DB_PATH = ".jollypixel/events.db";
|
|
7
|
+
export declare const STATE_GITIGNORE_CONTENT = "state.json\nevents.db\nevents.db-journal\nevents.db-wal\n";
|
|
8
|
+
export declare const ASSET_EVENT_PREFIX = "asset.";
|
|
9
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B,eAAO,MAAM,qBAAqB,4BAAmC,CAAC;AACtE,eAAO,MAAM,qBAAqB,2BAAkC,CAAC;AACrE,eAAO,MAAM,oBAAoB,2BAAkC,CAAC;AACpE,eAAO,MAAM,cAAc,0BAAiC,CAAC;AAE7D,eAAO,MAAM,uBAAuB,8DAInC,CAAC;AAEF,eAAO,MAAM,kBAAkB,WAAW,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import { STATE_DIRECTORY } from "@jolly-pixel/asset-source";
|
|
3
|
+
export { STATE_DIRECTORY };
|
|
4
|
+
export const IDENTITY_SIDECAR_PATH = `${STATE_DIRECTORY}/assets.json`;
|
|
5
|
+
export const PROJECTION_STATE_PATH = `${STATE_DIRECTORY}/state.json`;
|
|
6
|
+
export const STATE_GITIGNORE_PATH = `${STATE_DIRECTORY}/.gitignore`;
|
|
7
|
+
export const EVENTS_DB_PATH = `${STATE_DIRECTORY}/events.db`;
|
|
8
|
+
export const STATE_GITIGNORE_CONTENT = `state.json
|
|
9
|
+
events.db
|
|
10
|
+
events.db-journal
|
|
11
|
+
events.db-wal
|
|
12
|
+
`;
|
|
13
|
+
export const ASSET_EVENT_PREFIX = "asset.";
|