UNPKG

@genart-api/core

Version:

Platform-independent extensible API for browser-based generative art

152 lines (151 loc) 6.54 kB
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; }