@genart-api/core
Version:
Platform-independent extensible API for browser-based generative art
152 lines (151 loc) • 6.54 kB
TypeScript
import type { Param, ParamSpecs } from "./params.js";
import type { PRNG } from "./random.js";
import type { ScreenConfig } from "./screen.js";
import type { Traits } from "./traits.js";
/**
* Platform defined presentation mode for the artwork:
*
* - `play`: default mode
* - `preview`: capturing, thumbnail, etc.
* - `edit`: platform has param editor active
*/
export type RunMode = "play" | "preview" | "edit";
/**
* A plugin component responsible to implement and/or negotiate **any** platform
* specific behavior of the overall {@link GenArtAPI} functionality. To
* repurpose an artwork for a different platform, artist should only require to
* switch out a single `<script>` tag in the HTML wrapper of their piece, but
* otherwise require **zero** code changes.
*/
export interface PlatformAdapter {
readonly mode: RunMode;
readonly screen: ScreenConfig;
readonly prng: PRNG;
readonly seed: string;
/**
* Human-readable but unique identifier for this platform adapter
* implementation.
*
* @remarks
* This ID should be derrived from the target art platform's name, domain
* name or package name, and can also include version info.
*
* External tooling (e.g. parameter editors) can utilize this information to
* inform/warn about compatibility. Also see {@link InfoMessage} for related
* use cases.
*/
readonly id: string;
/**
* Platform supplied ID of the person/agent collecting/creating/minting the
* current artwork. Undefined if the platform doesn't support this concept.
*
* @remarks
* This API is not intended to be tied up with crypto/NFT-based concepts,
* even though currently it's likely only NFT platforms will or can provide
* this kind of information.
*
* Currently, there're no guarantees or constraints for this value. Even the
* concrete meaning & stability of a "collector" value here is also left
* wide open on purpose. For a custom digital art online store this could be
* the name of the collector/customer, but on supporting NFT platforms it
* would likely be the address of the person/agent who minted the artwork.
*
* Also see {@link PlatformAdapter.iteration}.
*/
readonly collector?: string;
/**
* Platform supplied iteration number of the artwork's edition.
* Undefined if platform doesn't support this concept.
*
* @remarks
* Also see {@link PlatformAdapter.collector}.
*/
readonly iteration?: number;
/**
* Called by {@link GenArtAPI.setParams} to receive parameter specs provided
* by the artwork and to allow the adapter to inject additional platform
* specific parameters into the given {@link ParamSpecs} object.
*
* @remarks
* **No platform-specific param initialization should happen at this
* stage.** The param specs passed to this function might be still not fully
* initialized (i.e. might still have missing default values). The same goes
* for any params injected here. Use {@link PlatformAdapter.initParams} for
* actual platform specific initialization (which will be called
* automatically if present, see lifecycle diagram).
*
* **If additional parameters are injected, the adapter MUST ensure their
* naming doesn't override existing params, i.e. these param names should be
* prefixed with a platform specific prefix (e.g. `foo:` or `__`)**
*
* @param params
*/
augmentParams?(params: ParamSpecs): ParamSpecs;
/**
* Called by {@link GenArtAPI.setParams} to receive fully initialized
* parameter specs provided by the artwork (and possibly augmented by
* {@link PlatformAdapter.augmentParams}. This function allows the adapter
* to prepare itself for param initialization (e.g. initiating a network
* request for loading parameter overrides). This function is async and MUST
* throw an error if pre-initialization failed on the adapter's side.
*
* @remarks
* The actual value parsing of individual parameter customization only
* happens later via {@link PlatformAdapter.updateParam} (which is also
* indirectly called by {@link GenArtAPI.setParams} after this function
* returns).
*
* @param params
*/
initParams?(params: ParamSpecs): Promise<void>;
/**
* Called by {@link GenArtAPI.updateParams} (and indirectly by
* {@link GenArtAPI.setParams}) to possibly augment/update a single param
* spec with any customizations sourced via platform-specific means (e.g.
* from URL query-string params).
*
* @remarks
* The function can return one of the following:
*
* 1. If the function returns `void`, no customizations found/performed and
* no notifications will be triggered.
* 3. If the function returns `{ update: { key1: any, key2: any, ...} }`,
* the given keys in the param spec will be modified/customized with
* their new values via calling {@link GenArtAPI.setParamValue} for each
* key-value pair. The keys to be updated MUST correspond to nested param
* specs defined by the main param type's {@link ParamImpl.params},
* otherwise an error will be thrown (see [Composite
* parameters](https://github.com/thi-ng/genart-api/blob/main/README.md#composite-parameters)
* for reference).
* 3. If the function returns `{ value: any }` and if that `value` is
* non-nullish, the param spec will be updated via
* {@link GenArtAPI.setParamValue}.
*
* If this function returned a `value` and/or `update`, and if the retured
* value(s) passed param type-specific validation (see
* {@link ParamImpl.validate}), then by default
* {@link GenArtAPI.setParamValue} emits a {@link ParamChangeMessage} message
* with the updated param spec.
*
* @param id
* @param spec
*/
updateParam(id: string, spec: Readonly<Param<any>>): Promise<{
value?: any;
update?: Record<string, any>;
} | void>;
/**
* See {@link GenArtAPI.setTraits}.
*
* @param traits
*/
setTraits?(traits: Traits): void;
/**
* Platform-specific handler to deal with capturing a thumbnail/preview of
* the art piece. (e.g. by sending a message to the parent window). See
* {@link GenArtAPI.capture}.
*
* @param el
*/
capture(el?: HTMLCanvasElement | SVGElement): void;
}