@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
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AssetKindHandler } from "./AssetKindHandler.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Resolves handlers in registration order, then falls back to `binary`.
|
|
4
|
+
*/
|
|
5
|
+
export declare class AssetKindRegistry {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(handlers?: Iterable<AssetKindHandler>);
|
|
8
|
+
register(handler: AssetKindHandler): this;
|
|
9
|
+
has(kind: string): boolean;
|
|
10
|
+
get(kind: string): AssetKindHandler;
|
|
11
|
+
resolve(path: string): AssetKindHandler;
|
|
12
|
+
kinds(): IterableIterator<string>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=AssetKindRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetKindRegistry.d.ts","sourceRoot":"","sources":["../../src/kinds/AssetKindRegistry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAY9D;;GAEG;AACH,qBAAa,iBAAiB;;gBAI1B,QAAQ,GAAE,QAAQ,CAAC,gBAAgB,CAAM;IAO3C,QAAQ,CACN,OAAO,EAAE,gBAAgB,GACxB,IAAI;IAuBP,GAAG,CACD,IAAI,EAAE,MAAM,GACX,OAAO;IAIV,GAAG,CACD,IAAI,EAAE,MAAM,GACX,gBAAgB;IAanB,OAAO,CACL,IAAI,EAAE,MAAM,GACX,gBAAgB;IAUnB,KAAK,IAAI,gBAAgB,CAAC,MAAM,CAAC;CAGlC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import picomatch from "picomatch";
|
|
3
|
+
import { binaryAssetHandler, BINARY_KIND } from "./handlers/binary.js";
|
|
4
|
+
import { UnknownAssetKindError } from "./errors/UnknownAssetKindError.js";
|
|
5
|
+
/**
|
|
6
|
+
* Resolves handlers in registration order, then falls back to `binary`.
|
|
7
|
+
*/
|
|
8
|
+
export class AssetKindRegistry {
|
|
9
|
+
#kinds = new Map();
|
|
10
|
+
constructor(handlers = []) {
|
|
11
|
+
for (const handler of handlers) {
|
|
12
|
+
this.register(handler);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
register(handler) {
|
|
16
|
+
if (handler.kind === BINARY_KIND) {
|
|
17
|
+
throw new TypeError(`"${BINARY_KIND}" is the built-in fallback kind and cannot be replaced.`);
|
|
18
|
+
}
|
|
19
|
+
if (this.#kinds.has(handler.kind)) {
|
|
20
|
+
throw new TypeError(`Asset kind "${handler.kind}" is already registered.`);
|
|
21
|
+
}
|
|
22
|
+
this.#kinds.set(handler.kind, {
|
|
23
|
+
handler,
|
|
24
|
+
isMatch: picomatch([...handler.match], { dot: true })
|
|
25
|
+
});
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
has(kind) {
|
|
29
|
+
return kind === BINARY_KIND || this.#kinds.has(kind);
|
|
30
|
+
}
|
|
31
|
+
get(kind) {
|
|
32
|
+
if (kind === BINARY_KIND) {
|
|
33
|
+
return binaryAssetHandler;
|
|
34
|
+
}
|
|
35
|
+
const registered = this.#kinds.get(kind);
|
|
36
|
+
if (registered === undefined) {
|
|
37
|
+
throw new UnknownAssetKindError(kind);
|
|
38
|
+
}
|
|
39
|
+
return registered.handler;
|
|
40
|
+
}
|
|
41
|
+
resolve(path) {
|
|
42
|
+
for (const { handler, isMatch } of this.#kinds.values()) {
|
|
43
|
+
if (isMatch(path)) {
|
|
44
|
+
return handler;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return binaryAssetHandler;
|
|
48
|
+
}
|
|
49
|
+
kinds() {
|
|
50
|
+
return this.#kinds.keys();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnknownAssetKindError.d.ts","sourceRoot":"","sources":["../../../src/kinds/errors/UnknownAssetKindError.ts"],"names":[],"mappings":"AAAA,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGpB,IAAI,EAAE,MAAM;CAMf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/kinds/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { UnknownAssetKindError } from "./UnknownAssetKindError.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AssetKindHandler } from "../AssetKindHandler.ts";
|
|
2
|
+
export declare const BINARY_KIND = "binary";
|
|
3
|
+
export interface BinaryAssetState {
|
|
4
|
+
bytes: Uint8Array;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Fallback handler that treats an asset's bytes as its state.
|
|
8
|
+
*/
|
|
9
|
+
export declare const binaryAssetHandler: AssetKindHandler<BinaryAssetState>;
|
|
10
|
+
//# sourceMappingURL=binary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary.d.ts","sourceRoot":"","sources":["../../../src/kinds/handlers/binary.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAS/D,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,CAAC,gBAAgB,CAwCjE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ASSET_CREATED, ASSET_DELETED, ASSET_UPDATED, decodeContent, parseAssetEvent } from "../../events/AssetEvents.js";
|
|
2
|
+
export const BINARY_KIND = "binary";
|
|
3
|
+
/**
|
|
4
|
+
* Fallback handler that treats an asset's bytes as its state.
|
|
5
|
+
*/
|
|
6
|
+
export const binaryAssetHandler = {
|
|
7
|
+
kind: BINARY_KIND,
|
|
8
|
+
match: ["**/*"],
|
|
9
|
+
create() {
|
|
10
|
+
return {
|
|
11
|
+
bytes: new Uint8Array()
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
apply(state, event) {
|
|
15
|
+
const parsed = parseAssetEvent(event);
|
|
16
|
+
if (!parsed.ok) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const assetEvent = parsed.val;
|
|
20
|
+
if (assetEvent.eventType === ASSET_CREATED ||
|
|
21
|
+
assetEvent.eventType === ASSET_UPDATED) {
|
|
22
|
+
state.bytes = decodeContent(assetEvent.eventData.content);
|
|
23
|
+
}
|
|
24
|
+
else if (assetEvent.eventType === ASSET_DELETED) {
|
|
25
|
+
state.bytes = new Uint8Array();
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
serialize(state) {
|
|
29
|
+
return Promise.resolve(state.bytes);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { binaryAssetHandler, BINARY_KIND } from "./binary.ts";
|
|
2
|
+
export type { BinaryAssetState } from "./binary.ts";
|
|
3
|
+
export { textureAssetHandler, TEXTURE_KIND } from "./texture.ts";
|
|
4
|
+
export type { TextureAssetHandlerOptions } from "./texture.ts";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/kinds/handlers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,mBAAmB,EACnB,YAAY,EACb,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AssetKindHandler } from "../AssetKindHandler.ts";
|
|
2
|
+
import { type BinaryAssetState } from "./binary.ts";
|
|
3
|
+
export declare const TEXTURE_KIND = "texture";
|
|
4
|
+
export interface TextureAssetHandlerOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Globs claiming texture paths.
|
|
7
|
+
* @default png, jpg, jpeg, webp, gif and bmp anywhere under the root
|
|
8
|
+
*/
|
|
9
|
+
match?: readonly string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function textureAssetHandler(options?: TextureAssetHandlerOptions): AssetKindHandler<BinaryAssetState>;
|
|
12
|
+
//# sourceMappingURL=texture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture.d.ts","sourceRoot":"","sources":["../../../src/kinds/handlers/texture.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,YAAY,YAAY,CAAC;AAqBtC,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,gBAAgB,CAAC,gBAAgB,CAAC,CAOpC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { binaryAssetHandler } from "./binary.js";
|
|
2
|
+
export const TEXTURE_KIND = "texture";
|
|
3
|
+
// CONSTANTS
|
|
4
|
+
const kDefaultMatch = [
|
|
5
|
+
"**/*.png",
|
|
6
|
+
"**/*.jpg",
|
|
7
|
+
"**/*.jpeg",
|
|
8
|
+
"**/*.webp",
|
|
9
|
+
"**/*.gif",
|
|
10
|
+
"**/*.bmp"
|
|
11
|
+
];
|
|
12
|
+
const kDefaultContentTypes = {
|
|
13
|
+
".png": "image/png",
|
|
14
|
+
".jpg": "image/jpeg",
|
|
15
|
+
".jpeg": "image/jpeg",
|
|
16
|
+
".webp": "image/webp",
|
|
17
|
+
".gif": "image/gif",
|
|
18
|
+
".bmp": "image/bmp"
|
|
19
|
+
};
|
|
20
|
+
export function textureAssetHandler(options = {}) {
|
|
21
|
+
return {
|
|
22
|
+
...binaryAssetHandler,
|
|
23
|
+
kind: TEXTURE_KIND,
|
|
24
|
+
match: options.match ?? kDefaultMatch,
|
|
25
|
+
contentTypes: kDefaultContentTypes
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { AssetKindHandler, AssetRoomBinding, SnapshotPolicy } from "./AssetKindHandler.ts";
|
|
2
|
+
export { AssetKindRegistry } from "./AssetKindRegistry.ts";
|
|
3
|
+
export { UnknownAssetKindError } from "./errors/index.ts";
|
|
4
|
+
export * from "./handlers/index.ts";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kinds/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,cAAc,qBAAqB,CAAC"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,MAAM,GAAG,SAAS,CAAC;AAE/B,wBAAgB,YAAY,IAAI,MAAM,CAMrC"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import type { CatalogProjection } from "../catalog/CatalogProjection.ts";
|
|
3
|
+
import { type AssetStaticHandlerOptions } from "../static/httpHandler.ts";
|
|
4
|
+
import { type AssetWorkspace, type AssetWorkspaceOptions } from "../workspace/createAssetWorkspace.ts";
|
|
5
|
+
export interface AssetCatalogPluginOptions {
|
|
6
|
+
projection: CatalogProjection;
|
|
7
|
+
/**
|
|
8
|
+
* @default DEFAULT_CATALOG_PATH
|
|
9
|
+
*/
|
|
10
|
+
path?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function createAssetCatalogPlugin(options: AssetCatalogPluginOptions): Plugin;
|
|
13
|
+
export type AssetStaticPluginOptions = AssetStaticHandlerOptions;
|
|
14
|
+
export declare function createAssetStaticPlugin(options: AssetStaticPluginOptions): Plugin;
|
|
15
|
+
export interface AssetWorkspacePluginOptions extends AssetWorkspaceOptions {
|
|
16
|
+
/**
|
|
17
|
+
* @default DEFAULT_CATALOG_PATH
|
|
18
|
+
*/
|
|
19
|
+
catalogPath?: string;
|
|
20
|
+
/**
|
|
21
|
+
* URL prefix the workspace is served under.
|
|
22
|
+
* @default DEFAULT_ASSET_PREFIX
|
|
23
|
+
*/
|
|
24
|
+
prefix?: string;
|
|
25
|
+
/**
|
|
26
|
+
* WebSocket upgrade path, kept separate from Vite HMR.
|
|
27
|
+
* @default DEFAULT_WEBSOCKET_PATH
|
|
28
|
+
*/
|
|
29
|
+
socketPath?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Called once the back-end is up, for a host needing its handles.
|
|
32
|
+
*/
|
|
33
|
+
onReady?: (workspace: AssetWorkspace) => void | Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export declare function createAssetWorkspacePlugin(options: AssetWorkspacePluginOptions): Plugin;
|
|
36
|
+
//# sourceMappingURL=vite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../../src/plugins/vite.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AASnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC3B,MAAM,sCAAsC,CAAC;AAE9C,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,iBAAiB,CAAC;IAC9B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GACjC,MAAM,CAkBR;AAED,MAAM,MAAM,wBAAwB,GAAG,yBAAyB,CAAC;AAEjE,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,MAAM,CAUR;AAED,MAAM,WAAW,2BAA4B,SAAQ,qBAAqB;IACxE;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,CACR,SAAS,EAAE,cAAc,KACtB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,2BAA2B,GACnC,MAAM,CA8CR"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { WebsocketTransport } from "@jolly-pixel/network/transport/websocket.ts";
|
|
2
|
+
import { DEFAULT_WEBSOCKET_PATH } from "@jolly-pixel/network/transport/constants.ts";
|
|
3
|
+
// Import Internal Dependencies
|
|
4
|
+
import { createCatalogHandler, DEFAULT_CATALOG_PATH } from "../catalog/httpHandler.js";
|
|
5
|
+
import { createAssetStaticHandler } from "../static/httpHandler.js";
|
|
6
|
+
import { createAssetWorkspace } from "../workspace/createAssetWorkspace.js";
|
|
7
|
+
export function createAssetCatalogPlugin(options) {
|
|
8
|
+
const { projection, path = DEFAULT_CATALOG_PATH } = options;
|
|
9
|
+
return {
|
|
10
|
+
name: "asset-server-catalog",
|
|
11
|
+
apply: "serve",
|
|
12
|
+
configureServer(server) {
|
|
13
|
+
server.middlewares.use(createCatalogHandler({
|
|
14
|
+
projection,
|
|
15
|
+
path
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function createAssetStaticPlugin(options) {
|
|
21
|
+
return {
|
|
22
|
+
name: "asset-server-static",
|
|
23
|
+
apply: "serve",
|
|
24
|
+
configureServer(server) {
|
|
25
|
+
server.middlewares.use(createAssetStaticHandler(options));
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function createAssetWorkspacePlugin(options) {
|
|
30
|
+
const { catalogPath = DEFAULT_CATALOG_PATH, prefix, socketPath = DEFAULT_WEBSOCKET_PATH, onReady, ...workspaceOptions } = options;
|
|
31
|
+
let workspace = null;
|
|
32
|
+
return {
|
|
33
|
+
name: "asset-server-workspace",
|
|
34
|
+
apply: "serve",
|
|
35
|
+
async configureServer(devServer) {
|
|
36
|
+
workspace = await createAssetWorkspace(workspaceOptions);
|
|
37
|
+
devServer.middlewares.use(createCatalogHandler({
|
|
38
|
+
projection: workspace.backend.catalog,
|
|
39
|
+
path: catalogPath
|
|
40
|
+
}));
|
|
41
|
+
devServer.middlewares.use(createAssetStaticHandler({
|
|
42
|
+
source: workspace.source,
|
|
43
|
+
kinds: workspace.backend.kinds,
|
|
44
|
+
prefix
|
|
45
|
+
}));
|
|
46
|
+
if (devServer.httpServer) {
|
|
47
|
+
new WebsocketTransport({
|
|
48
|
+
path: socketPath,
|
|
49
|
+
httpServer: devServer.httpServer,
|
|
50
|
+
server: workspace.server
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
await onReady?.(workspace);
|
|
54
|
+
},
|
|
55
|
+
async closeBundle() {
|
|
56
|
+
await workspace?.close();
|
|
57
|
+
workspace = null;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as network from "@jolly-pixel/network";
|
|
2
|
+
import type { AssetRoomBinding } from "../kinds/AssetKindHandler.ts";
|
|
3
|
+
export interface AssetRoomMessage {
|
|
4
|
+
readonly type: string;
|
|
5
|
+
readonly data: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface AssetArbitration<TCommand = unknown> {
|
|
8
|
+
readonly command: TCommand;
|
|
9
|
+
commit?(): void;
|
|
10
|
+
}
|
|
11
|
+
export interface AssetLiveProtocol<TCommand = unknown> {
|
|
12
|
+
readonly commandEventType: string;
|
|
13
|
+
readonly protocols: network.MessageProtocols;
|
|
14
|
+
parse(payload: unknown): TCommand | null;
|
|
15
|
+
snapshot(): unknown;
|
|
16
|
+
arbitrate(command: TCommand, clientId: string): AssetArbitration<TCommand> | null;
|
|
17
|
+
broadcast?(command: TCommand): AssetRoomMessage;
|
|
18
|
+
}
|
|
19
|
+
export declare class AssetRoomExtension<TCommand = unknown> extends network.Extension {
|
|
20
|
+
#private;
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly protocols: network.MessageProtocols;
|
|
24
|
+
constructor(binding: AssetRoomBinding, protocol: AssetLiveProtocol<TCommand>);
|
|
25
|
+
onClientConnect(client: network.ClientHandle): void;
|
|
26
|
+
onClientDisconnect(): void;
|
|
27
|
+
onMessage(clientId: string, payload: unknown, context: network.RoomContext): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=AssetRoomExtension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetRoomExtension.d.ts","sourceRoot":"","sources":["../../src/rooms/AssetRoomExtension.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAC;AAGhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB,CAAC,QAAQ,GAAG,OAAO;IAClD,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B,MAAM,CAAC,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,OAAO;IACnD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,CAAC;IAE7C,KAAK,CACH,OAAO,EAAE,OAAO,GACf,QAAQ,GAAG,IAAI,CAAC;IAEnB,QAAQ,IAAI,OAAO,CAAC;IAEpB,SAAS,CACP,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAErC,SAAS,CAAC,CACR,OAAO,EAAE,QAAQ,GAChB,gBAAgB,CAAC;CACrB;AAED,qBAAa,kBAAkB,CAC7B,QAAQ,GAAG,OAAO,CAClB,SAAQ,OAAO,CAAC,SAAS;;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,CAAC;gBAM3C,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,iBAAiB,CAAC,QAAQ,CAAC;IAWvC,eAAe,CACb,MAAM,EAAE,OAAO,CAAC,YAAY,GAC3B,IAAI;IAOP,kBAAkB,IAAI,IAAI;IAIpB,SAAS,CACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,CAAC,WAAW,GAC3B,OAAO,CAAC,IAAI,CAAC;CA6BjB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import * as network from "@jolly-pixel/network";
|
|
3
|
+
export class AssetRoomExtension extends network.Extension {
|
|
4
|
+
id;
|
|
5
|
+
name;
|
|
6
|
+
protocols;
|
|
7
|
+
#assetId;
|
|
8
|
+
#protocol;
|
|
9
|
+
constructor(binding, protocol) {
|
|
10
|
+
super();
|
|
11
|
+
this.id = binding.roomId;
|
|
12
|
+
this.name = binding.kind;
|
|
13
|
+
this.protocols = protocol.protocols;
|
|
14
|
+
this.#assetId = binding.assetId;
|
|
15
|
+
this.#protocol = protocol;
|
|
16
|
+
}
|
|
17
|
+
onClientConnect(client) {
|
|
18
|
+
client.send({
|
|
19
|
+
type: "snapshot",
|
|
20
|
+
data: this.#protocol.snapshot()
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
onClientDisconnect() {
|
|
24
|
+
return void 0;
|
|
25
|
+
}
|
|
26
|
+
async onMessage(clientId, payload, context) {
|
|
27
|
+
const command = this.#protocol.parse(payload);
|
|
28
|
+
if (command === null) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const arbitration = this.#protocol.arbitrate(command, clientId);
|
|
32
|
+
if (arbitration === null) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const appended = await context.eventStore.append({
|
|
36
|
+
assetType: this.name,
|
|
37
|
+
assetId: this.#assetId,
|
|
38
|
+
eventType: this.#protocol.commandEventType,
|
|
39
|
+
eventData: arbitration.command
|
|
40
|
+
});
|
|
41
|
+
if (!appended) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
arbitration.commit?.();
|
|
45
|
+
context.room.broadcast(this.#protocol.broadcast?.(arbitration.command) ?? {
|
|
46
|
+
type: "command",
|
|
47
|
+
data: arbitration.command
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { AssetRoomExtension } from "./AssetRoomExtension.ts";
|
|
2
|
+
export type { AssetArbitration, AssetLiveProtocol, AssetRoomMessage } from "./AssetRoomExtension.ts";
|
|
3
|
+
export { assetRoomName, parseAssetRoomName, registerAssetRooms } from "./registerAssetRooms.ts";
|
|
4
|
+
export type { AssetRoomName, AssetRoomsOptions } from "./registerAssetRooms.ts";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rooms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EACnB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,aAAa,EACb,iBAAiB,EAClB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Server } from "@jolly-pixel/network";
|
|
2
|
+
import { assetRoomName, parseAssetRoomName, type AssetRoomName } from "@jolly-pixel/asset";
|
|
3
|
+
import type { AssetKindRegistry } from "../kinds/AssetKindRegistry.ts";
|
|
4
|
+
import type { CatalogProjection } from "../catalog/CatalogProjection.ts";
|
|
5
|
+
import type { AssetStateStore } from "../sync/AssetStateStore.ts";
|
|
6
|
+
import type { AssetProjector } from "../sync/AssetProjector.ts";
|
|
7
|
+
import type { SnapshotScheduler } from "../sync/SnapshotScheduler.ts";
|
|
8
|
+
import { type Logger } from "../logger.ts";
|
|
9
|
+
export { assetRoomName, parseAssetRoomName, type AssetRoomName };
|
|
10
|
+
export interface AssetRoomsOptions {
|
|
11
|
+
server: Server;
|
|
12
|
+
kinds: AssetKindRegistry;
|
|
13
|
+
catalog: CatalogProjection;
|
|
14
|
+
states: AssetStateStore;
|
|
15
|
+
projector: AssetProjector;
|
|
16
|
+
scheduler: SnapshotScheduler;
|
|
17
|
+
graceMs?: number;
|
|
18
|
+
logger?: Logger;
|
|
19
|
+
}
|
|
20
|
+
export declare function registerAssetRooms(options: AssetRoomsOptions): () => void;
|
|
21
|
+
//# sourceMappingURL=registerAssetRooms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerAssetRooms.d.ts","sourceRoot":"","sources":["../../src/rooms/registerAssetRooms.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,MAAM,EACP,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,aAAa,EACb,kBAAkB,EAClB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAKvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAEL,KAAK,MAAM,EACZ,MAAM,cAAc,CAAC;AAKtB,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,KAAK,aAAa,EACnB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,iBAAiB,CAAC;IACzB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAoBD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,iBAAiB,GACzB,MAAM,IAAI,CA+EZ"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { AssetId, assetRoomName, parseAssetRoomName } from "@jolly-pixel/asset";
|
|
2
|
+
// Import Internal Dependencies
|
|
3
|
+
import { AssetRoomExtension } from "./AssetRoomExtension.js";
|
|
4
|
+
import { silentLogger } from "../logger.js";
|
|
5
|
+
// Re-exported so a host wiring rooms needs one import, not two. The
|
|
6
|
+
// definitions live in `@jolly-pixel/asset` because the browser needs them
|
|
7
|
+
// to build the same room name.
|
|
8
|
+
export { assetRoomName, parseAssetRoomName };
|
|
9
|
+
function extensionFactory(handler) {
|
|
10
|
+
const { createExtension, live } = handler;
|
|
11
|
+
if (createExtension !== undefined) {
|
|
12
|
+
return createExtension;
|
|
13
|
+
}
|
|
14
|
+
if (live === undefined) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return (binding) => new AssetRoomExtension(binding, live(binding));
|
|
18
|
+
}
|
|
19
|
+
export function registerAssetRooms(options) {
|
|
20
|
+
const { server, kinds, catalog, states, projector, scheduler, graceMs, logger = silentLogger() } = options;
|
|
21
|
+
server.setRoomResolver(async (roomName) => {
|
|
22
|
+
function refuse(reason, metadata = {}) {
|
|
23
|
+
logger
|
|
24
|
+
.withMetadata({
|
|
25
|
+
room: roomName,
|
|
26
|
+
reason, ...metadata
|
|
27
|
+
})
|
|
28
|
+
.warn("asset room refused");
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const parsed = parseAssetRoomName(roomName);
|
|
32
|
+
if (parsed === null) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const { kind, assetId } = parsed;
|
|
36
|
+
if (!kinds.has(kind)) {
|
|
37
|
+
return refuse("unknown kind");
|
|
38
|
+
}
|
|
39
|
+
const createRoomExtension = extensionFactory(kinds.get(kind));
|
|
40
|
+
if (createRoomExtension === null) {
|
|
41
|
+
return refuse("kind has no extension");
|
|
42
|
+
}
|
|
43
|
+
const id = new AssetId(assetId);
|
|
44
|
+
if (!catalog.catalog.has(id) ||
|
|
45
|
+
catalog.catalog.get(id).kind !== kind) {
|
|
46
|
+
return refuse("unknown asset");
|
|
47
|
+
}
|
|
48
|
+
const entry = await states.acquire(assetId, kind);
|
|
49
|
+
const binding = {
|
|
50
|
+
assetId,
|
|
51
|
+
kind,
|
|
52
|
+
roomId: roomName,
|
|
53
|
+
state: entry.state
|
|
54
|
+
};
|
|
55
|
+
const extension = createRoomExtension(binding);
|
|
56
|
+
if (extension.id !== roomName) {
|
|
57
|
+
states.release(assetId);
|
|
58
|
+
return refuse("extension id must match the room name", { extensionId: extension.id });
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
extension,
|
|
62
|
+
graceMs,
|
|
63
|
+
onEvict: async () => {
|
|
64
|
+
await scheduler.flush(assetId);
|
|
65
|
+
await projector.flush(assetId);
|
|
66
|
+
states.release(assetId);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
return () => server.setRoomResolver(null);
|
|
71
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AssetKindRegistry } from "../kinds/AssetKindRegistry.ts";
|
|
2
|
+
export declare const DEFAULT_CONTENT_TYPE = "application/octet-stream";
|
|
3
|
+
export declare const DEFAULT_CONTENT_TYPES: Readonly<Record<string, string>>;
|
|
4
|
+
export declare function contentTypesFromKinds(kinds: AssetKindRegistry): Record<string, string>;
|
|
5
|
+
export declare function resolveContentType(assetPath: string, table?: Readonly<Record<string, string>>): string;
|
|
6
|
+
//# sourceMappingURL=contentTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentTypes.d.ts","sourceRoot":"","sources":["../../src/static/contentTypes.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,eAAO,MAAM,oBAAoB,6BAA6B,CAAC;AAC/D,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUlE,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAaxB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAyB,GAC9D,MAAM,CAMR"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Import Node.js Dependencies
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export const DEFAULT_CONTENT_TYPE = "application/octet-stream";
|
|
4
|
+
export const DEFAULT_CONTENT_TYPES = {
|
|
5
|
+
".json": "application/json; charset=utf-8",
|
|
6
|
+
".txt": "text/plain; charset=utf-8",
|
|
7
|
+
".png": "image/png",
|
|
8
|
+
".jpg": "image/jpeg",
|
|
9
|
+
".jpeg": "image/jpeg",
|
|
10
|
+
".webp": "image/webp",
|
|
11
|
+
".gif": "image/gif",
|
|
12
|
+
".bmp": "image/bmp",
|
|
13
|
+
".svg": "image/svg+xml"
|
|
14
|
+
};
|
|
15
|
+
export function contentTypesFromKinds(kinds) {
|
|
16
|
+
const table = {
|
|
17
|
+
...DEFAULT_CONTENT_TYPES
|
|
18
|
+
};
|
|
19
|
+
for (const kind of kinds.kinds()) {
|
|
20
|
+
Object.assign(table, kinds.get(kind).contentTypes);
|
|
21
|
+
}
|
|
22
|
+
return table;
|
|
23
|
+
}
|
|
24
|
+
export function resolveContentType(assetPath, table = DEFAULT_CONTENT_TYPES) {
|
|
25
|
+
const extension = path.posix.extname(assetPath).toLowerCase();
|
|
26
|
+
return table[extension] ?? DEFAULT_CONTENT_TYPE;
|
|
27
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import { type AssetSource } from "@jolly-pixel/asset-source";
|
|
3
|
+
import type { AssetKindRegistry } from "../kinds/AssetKindRegistry.ts";
|
|
4
|
+
export declare const DEFAULT_ASSET_PREFIX = "/assets/";
|
|
5
|
+
export type AssetStaticHandler = (request: IncomingMessage, response: ServerResponse, next: () => void) => void;
|
|
6
|
+
export interface AssetStaticHandlerOptions {
|
|
7
|
+
source: AssetSource;
|
|
8
|
+
/**
|
|
9
|
+
* URL prefix the workspace is mounted under. A missing trailing slash is
|
|
10
|
+
* added, so `/assets` and `/assets/` behave the same.
|
|
11
|
+
* @default DEFAULT_ASSET_PREFIX
|
|
12
|
+
*/
|
|
13
|
+
prefix?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Kinds contributing content types for the extensions they claim.
|
|
16
|
+
*/
|
|
17
|
+
kinds?: AssetKindRegistry;
|
|
18
|
+
/**
|
|
19
|
+
* Extension-to-content-type entries taking precedence over the kinds.
|
|
20
|
+
*/
|
|
21
|
+
contentTypes?: Readonly<Record<string, string>>;
|
|
22
|
+
}
|
|
23
|
+
export declare function createAssetStaticHandler(options: AssetStaticHandlerOptions): AssetStaticHandler;
|
|
24
|
+
//# sourceMappingURL=httpHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpHandler.d.ts","sourceRoot":"","sources":["../../src/static/httpHandler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACf,MAAM,WAAW,CAAC;AAInB,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAiBvE,eAAO,MAAM,oBAAoB,aAAmB,CAAC;AAErD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,MAAM,IAAI,KACb,IAAI,CAAC;AAEV,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B;;OAEG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GACjC,kBAAkB,CAqEpB"}
|