本文へ移動
SDK ガイド / World・読み取り

World・読み取り

ローカルモデルの生成、取得、購読と操作可否。

生成と取得

World.create は新規作成、World.open は同じIDの復元。本人と保存先を明示します。接続・公開は行いません。

TypeScript · シグネチャ
connect(options: {
  identity: Identity;
  access: RelayAccess | (() => Promise<RelayAccess>);
} & ({ discovery: string; endpoints?: never } | {
  endpoints: readonly string[]; discovery?: never;
})): Promise<Connection>;

World.create(options: {
  identity: Identity;
  name: string;
  source?: WorldData;
  storage?: Storage;
  blobs?: Storage;
}): Promise<World>;

World.open(source: WorldData | Storage, options: {
  identity: Identity;
  storage?: Storage;
  blobs?: Storage;
}): Promise<World>;

World

read / watch は同期。watch は登録時に初回通知します。close の前に利用中のSessionから退出します。

TypeScript · シグネチャ
interface World {
  readonly id: string;
  readonly subject: string;
  readonly scopes: Scopes;
  readonly scenes: Scenes;
  readonly definitions: Definitions;
  readonly objects: Objects;
  readonly assets: Assets;
  readonly chat: Chat;
  readonly invitations: WorldInvitations;
  readonly keepers: Keepers;

  read(): DeepReadonly<ModelInfo>;
  read<K extends Collection>(query: ReadQuery<K>): ReadPage<Records[K]>;
  watch(listener: (info: DeepReadonly<ModelInfo>) => void, options?: WatchOptions): () => void;
  watch<K extends Collection>(query: ReadQuery<K>, listener: (page: ReadPage<Records[K]>) => void, options?: WatchOptions): () => void;
  availability(operation: DeepReadonly<WorldOperation>): Availability;
  rename(name: string): Promise<ChangeResult>;
  close(): Promise<void>;
}

read / watch

limit は既定100・最大500。next を同じ条件の cursor に渡します。取得済みで閲覧可能なデータだけが対象です。related は参照先のレコードで、ファイル実体は含みません。

TypeScript · シグネチャ
interface DeepReadonlyArray<T> extends ReadonlyArray<DeepReadonly<T>> {}
type DeepReadonly<T> = T extends readonly unknown[]
  ? number extends T['length'] ? DeepReadonlyArray<T[number]> : { readonly [K in keyof T]: DeepReadonly<T[K]> }
  : T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T;

interface ModelInfo {
  name: string;
  owner: string;
  revision: number;
  rootScope: string;
  rootScene: string;
  writable: boolean;
  complete: boolean;
}

interface Records {
  scopes: Scope;
  scenes: Scene;
  definitions: Definition;
  objects: WorldObject;
  assets: Asset;
  messages: Message;
  keepers: KeeperRecord;
  invitations: InvitationRecord;
}
type Collection = keyof Records;

interface Bounds {
  left: number;
  top: number;
  right: number;
  bottom: number;
}

type ReadQuery<K extends Collection = Collection> = K extends Collection
  ? {
      from: K;
      id?: string;
      limit?: number;
      cursor?: string;
    } & (K extends 'objects'
      ? { scope?: string; scene?: string; bounds?: Bounds }
      : K extends 'scenes' | 'definitions' | 'assets' | 'messages'
        ? { scope?: string }
        : {})
  : never;

interface RelatedRecords {
  readonly scopes: Readonly<Record<string, DeepReadonly<Scope>>>;
  readonly scenes: Readonly<Record<string, DeepReadonly<Scene>>>;
  readonly definitions: Readonly<Record<string, DeepReadonly<Definition>>>;
  readonly assets: Readonly<Record<string, DeepReadonly<Asset>>>;
}

interface ReadPage<T> {
  readonly items: readonly DeepReadonly<T>[];
  readonly related: RelatedRecords;
  readonly total: number;
  readonly next: string | null;
  readonly revision: number;
}

操作可否

allowed と reason で現在の可否を判別します。成功を予約するものではなく、実行時のエラー処理も必要です。

TypeScript · シグネチャ
type WorldOperation =
  | { operation: 'rename' | 'scopes.create' | 'save' | 'export' | 'merge' | 'close' }
  | { operation: 'scopes.remove' | 'scenes.configure' | 'scenes.remove'
      | 'objects.move' | 'objects.edit' | 'objects.remove'
      | 'assets.read' | 'assets.remove' | 'chat.remove' | 'invitations.revoke'; id: string }
  | { operation: 'scenes.create' | 'assets.import' | 'chat.send'; scope: string }
  | { operation: 'definitions.set'; scope: string; id?: string }
  | { operation: 'objects.place'; definition: string; placement: Placement }
  | { operation: 'invitations.create'; actions: WorldGrant['actions'] }
  | { operation: 'keepers.appoint'; subject: string };

type Availability =
  | { allowed: true; reason: null }
  | { allowed: false; reason:
      'closed' | 'missing' | 'forbidden' | 'connecting'
      | 'writer-absent' | 'incomplete' | 'in-use' };

const moving = world.availability({ operation: 'objects.move', id: objectId });
const placing = world.availability({ operation: 'objects.place', definition: definitionId, placement });

編集結果

変更結果は revision と accepted(local / shared)。新規作成は id も返します。

TypeScript · シグネチャ
interface ChangeResult {
  revision: number;
  accepted: 'local' | 'shared';
}
type Created = ChangeResult & { id: string };

リファレンスの目次