diff --git a/packages/page/src/asset.ts b/packages/page/src/asset.ts index 6de0e39..defaad7 100644 --- a/packages/page/src/asset.ts +++ b/packages/page/src/asset.ts @@ -60,7 +60,7 @@ class AssetNode { export type { Asset, AssetNode } -export class AssetLeaf { +export class AssetAbst { constructor(private readonly load: (() => Awaitable) | string) {} instantiate(parent: Base): PromiseLike { diff --git a/packages/page/src/find.ts b/packages/page/src/find.ts index 245face..25e2a82 100644 --- a/packages/page/src/find.ts +++ b/packages/page/src/find.ts @@ -126,15 +126,15 @@ class FileNameTransition extends Transition { export type { Transition } type NextPath = Readonly -export type Next = Readonly<{ leaf: Leaf; relPath: NextPath }> +export type Next = Readonly<{ abst: Abst; relPath: NextPath }> -export class Indices { - readonly moduleNameMap = new ModuleNameTransition>() - readonly stemMap = new ModuleNameTransition>() - readonly fileNameMap = new FileNameTransition>() +export class Indices { + readonly moduleNameMap = new ModuleNameTransition>() + readonly stemMap = new ModuleNameTransition>() + readonly fileNameMap = new FileNameTransition>() - addRoute(leaf: Leaf, relPath: NextPath): void { - const next = { leaf, relPath } + addRoute(abst: Abst, relPath: NextPath): void { + const next = { abst, relPath } const moduleSteps = PathSteps.fromRelativeModuleName(relPath.moduleName) const stemSteps = PathSteps.fromRelativeModuleName(relPath.stem) const fileSteps = PathSteps.fromRelativeFileName(relPath.fileName) @@ -144,7 +144,7 @@ export class Indices { } } -export interface TreeLeaf { +export interface TreeAbst { readonly instantiate: (parent: Tree, path: NextPath) => PromiseLike } @@ -156,7 +156,7 @@ interface TreeNode { type Content = | ((...a: never) => unknown) - | PromiseLike<{ [P in Key]: Transition>> }> + | PromiseLike<{ [P in Key]: Transition>> }> const undef = Promise.resolve(undefined) @@ -206,7 +206,7 @@ export const find = < trie.value?.reduceRight((cont, { next, epsilon }) => { return r => r ?? - next.leaf.instantiate(node, next.relPath).then(inst => { + next.abst.instantiate(node, next.relPath).then(inst => { return epsilon ? search(inst, key, final).then(cont) : check(inst, key, final ?? true).then(cont) diff --git a/packages/page/src/page.ts b/packages/page/src/page.ts index 94b94b3..b925789 100644 --- a/packages/page/src/page.ts +++ b/packages/page/src/page.ts @@ -4,9 +4,9 @@ import { type Pairs, type List, iteratePairs, listItems } from './items' import { constProp } from './util' import { type Delay, delay } from './delay' import { type RelPath, PathSteps, concatFileName } from './filename' -import { type Asset, type AssetModule, AssetLeaf } from './asset' +import { type Asset, type AssetModule, AssetAbst } from './asset' import type { Loaded, MainModule, Dir, TreeNode, Inst } from './tree' -import { Tree, TreeLeafImpl } from './tree' +import { Tree, TreeAbstImpl } from './tree' const dummyRelPath: Readonly = { moduleName: '', @@ -64,13 +64,13 @@ class PageFactory< Args extends unknown[] > { readonly basis: This - readonly leaf: TreeLeafImpl + readonly abst: TreeAbstImpl constructor( This: PageConstructor, arg: NewArg, args: Args, - content: TreeLeafImpl['content'] + content: TreeAbstImpl['content'] ) { this.basis = new This(...args) if (arg.parsePath != null) { @@ -87,35 +87,35 @@ class PageFactory< } const init = { rootURL: arg.url != null ? new URL(arg.url) : undefined, - fileName: TreeLeafImpl.currentFileName(), + fileName: TreeAbstImpl.currentFileName(), basis: this.basis, content, Base: This.Base } - this.leaf = TreeLeafImpl.decorate(init) + this.abst = TreeAbstImpl.decorate(init) } createSubpage( dir: Dir, - content: TreeLeafImpl['content'], + content: TreeAbstImpl['content'], relPath: Readonly - ): TreeLeafImpl { + ): TreeAbstImpl { const arg = { - rootURL: this.leaf.rootURL, - fileName: concatFileName(this.leaf.fileName, relPath?.fileName), + rootURL: this.abst.rootURL, + fileName: concatFileName(this.abst.fileName, relPath?.fileName), basis: this.basis, content, - Base: this.leaf.Base + Base: this.abst.Base } - const leaf = TreeLeafImpl.decorate(arg) - dir.addRoute(leaf, relPath) - return leaf + const abst = TreeAbstImpl.decorate(arg) + dir.addRoute(abst, relPath) + return abst } async createModuleDirectory( arg: Readonly> ): Promise> { - const dir = TreeLeafImpl.createDirectory() + const dir = TreeAbstImpl.createDirectory() const substPath = (path: string): Awaitable => arg.substitutePath != null ? Reflect.apply(arg.substitutePath, this.basis, [path]) @@ -135,9 +135,9 @@ class PageFactory< fileName: PathSteps.normalize(path) } } - const leaf = this.leaf.getTreeLeaf(load) - if (leaf != null) { - dir.addRoute(leaf, relPath) + const abst = this.abst.getTreeAbst(load) + if (abst != null) { + dir.addRoute(abst, relPath) } else if (typeof load === 'function') { this.createSubpage(dir, load, relPath) } else { @@ -148,8 +148,8 @@ class PageFactory< if (arg.assets != null) { for await (const [path, load] of iteratePairs(arg.assets, this.basis)) { const loader = load ?? (await substPath(path)) - const leaf = new AssetLeaf>(loader) - const pair = { leaf, relPath: dummyRelPath } + const abst = new AssetAbst>(loader) + const pair = { abst, relPath: dummyRelPath } dir.fileNameMap.addRoute(PathSteps.fromRelativeFileName(path), pair) } } @@ -159,18 +159,18 @@ class PageFactory< async createPaginateDirectory( arg: Readonly> ): Promise> { - const dir = TreeLeafImpl.createDirectory() + const dir = TreeAbstImpl.createDirectory() const rawPageSize = arg.pageSize ?? 10 const pageSize = rawPageSize >= 1 ? rawPageSize : 1 const load = arg.load - const allItems = await listItems(arg.items, this.leaf.basis) + const allItems = await listItems(arg.items, this.abst.basis) const numAllItems = allItems.length const numPages = Math.ceil(numAllItems / pageSize) const pages: Array> = [] for (let pageIndex = 0; pageIndex < numPages; pageIndex++) { const itemIndex = pageIndex * pageSize const items = allItems.slice(itemIndex, itemIndex + pageSize) - const relPath = this.leaf.basis.paginatePath(pageIndex) + const relPath = this.abst.basis.paginatePath(pageIndex) const page = undefined as unknown as This // dummy const pagi = { pages, page, pageIndex, items, itemIndex, numAllItems } const content = (): Loaded => Reflect.apply(load, pagi.page, [pagi]) @@ -203,7 +203,7 @@ export class Page< type F = PageFactory & This, Impl, Args> const dir = delay(async () => await factory.createModuleDirectory(arg)) const factory: F = new PageFactory(this, arg, args, dir) - return factory.leaf.basis + return factory.abst.basis } static paginate< @@ -220,7 +220,7 @@ export class Page< type F = PageFactory & This, Impl, Args> const dir = delay(async () => await factory.createPaginateDirectory(arg)) const factory: F = new PageFactory(this, arg, args, dir) - return factory.leaf.basis + return factory.abst.basis } parsePath(fileName: string): ParsePath { diff --git a/packages/page/src/ref.ts b/packages/page/src/ref.ts index 3ac9e9b..3e9b134 100644 --- a/packages/page/src/ref.ts +++ b/packages/page/src/ref.ts @@ -1,7 +1,7 @@ import type { ModuleName } from '../../vite-plugin-minissg/src/module' import { type Awaitable, raise } from '../../vite-plugin-minissg/src/util' import { type Delay, delay } from './delay' -import type { Transition, Next, TreeLeaf } from './find' +import type { Transition, Next, TreeAbst } from './find' import type { RelPath } from './filename' interface SomeNode { @@ -10,7 +10,7 @@ interface SomeNode { interface TreeNode extends SomeNode { readonly content: | ((...a: never) => unknown) - | PromiseLike<{ moduleNameMap: Transition>> }> + | PromiseLike<{ moduleNameMap: Transition>> }> readonly findChild: () => PromiseLike readonly parent: Tree | undefined readonly root: Tree @@ -118,7 +118,7 @@ const descendants = , Inst extends SomeNode>( const k = (i: number): Awaitable => { const next = branches[i] if (next == null) return skip.then(last).then(cont) - return next.leaf + return next.abst .instantiate(tree, next.relPath) .then(node => descendants(node, wait, except, queue, () => k(i + 1))) } diff --git a/packages/page/src/tree.ts b/packages/page/src/tree.ts index f84e953..ddb3824 100644 --- a/packages/page/src/tree.ts +++ b/packages/page/src/tree.ts @@ -8,7 +8,7 @@ import { Memo } from './memo' import { PathSteps, FileName, concatName, concatFileName } from './filename' import type { RelPath } from './filename' import { type Next, Indices, find } from './find' -import type { Asset, AssetNode, AssetLeaf } from './asset' +import type { Asset, AssetNode, AssetAbst } from './asset' import { Ref } from './ref' export type MainModule = Readonly<{ main: minissg.Main }> @@ -21,10 +21,10 @@ export const isMinissgMainModule = (x: unknown): x is MainModule => type TreeImpl = | TreeNodeImpl - | TreeLeafImpl + | TreeAbstImpl const currentNode = new AsyncLocalStorage>() -const internal = new WeakMap | TreeLeaf>() +const internal = new WeakMap | TreeAbst>() const setTree = ( tree: TreeImpl, @@ -33,17 +33,17 @@ const setTree = ( const getTree = ( obj: object -): TreeNode | TreeLeaf | undefined => internal.get(obj) +): TreeNode | TreeAbst | undefined => internal.get(obj) const isTreeNodeOf = ( x: TreeNode, Base_: abstract new (...a: never) => Base ): x is TreeNode => x.module instanceof Base_ -const isTreeLeafOf = ( - x: TreeLeaf, +const isTreeAbstOf = ( + x: TreeAbst, Base_: abstract new (...a: never) => Base -): x is TreeLeaf => x.basis instanceof Base_ +): x is TreeAbst => x.basis instanceof Base_ const getTreeImpl = ( obj: Tree @@ -124,9 +124,9 @@ const findByPath = async ( if (typeof node.content === 'function') return undefined const routes = Array.from((await node.content).moduleNameMap.routes()) nodes = [] - for (const { leaf, relPath } of routes) { + for (const { abst, relPath } of routes) { if (relPath.moduleName === step) { - nodes.push(await leaf.instantiate(node, relPath)) + nodes.push(await abst.instantiate(node, relPath)) } } } else if (step === 0) { @@ -155,7 +155,7 @@ const subnodes = async function* ( for (const { trie } of Array.from(index.walk(dir ? [''] : [])).reverse()) { for (const { next, epsilon } of trie.value ?? []) { if (!epsilon || (next.relPath?.moduleName ?? '') === '') { - yield await next.leaf.instantiate(self, next.relPath) + yield await next.abst.instantiate(self, next.relPath) } } } @@ -180,8 +180,8 @@ const findChild = async ( const moduleName = self.moduleName let context: minissg.Context = self while (typeof mod === 'object' && mod != null) { - const leaf = self._leaf.getTreeLeaf(mod) - if (leaf != null) return await leaf.instantiate(self, null) + const abst = self._abst.getTreeAbst(mod) + if (abst != null) return await abst.instantiate(self, null) if (!hasMinissgMain(mod)) break context = Object.freeze({ moduleName, module: mod, parent: context }) mod = await mod.main(context) @@ -211,12 +211,12 @@ const fetch = async (self: TreeNode): Promise => { } const children = async ( - self: TreeNode | TreeLeaf + self: TreeNode | TreeAbst ): Promise>> => { if (typeof self.content === 'function') return [] const routes = (await self.content).moduleNameMap.routes() return (function* iterator(): Iterable> { - for (const { leaf, relPath } of routes) yield { leaf: leaf.basis, relPath } + for (const { abst, relPath } of routes) yield { abst: abst.basis, relPath } })() } @@ -224,15 +224,15 @@ const entries = async (self: TreeNode): Promise => { if (typeof self.content === 'function') return [] const routes = (await self.content).moduleNameMap.routes() return (function* iterator(): Iterable<[string, Awaitable]> { - for (const { leaf, relPath } of routes) { + for (const { abst, relPath } of routes) { const mod = async (): Promise => - (await leaf.instantiate(self, relPath)).module + (await abst.instantiate(self, relPath)).module yield [relPath.moduleName ?? '', delay(mod)] } })() } -export type Dir = Indices, AssetLeaf>> +export type Dir = Indices, AssetAbst>> // these are private in each node and therefore safely hidden from other nodes. type Public = Omit @@ -243,8 +243,8 @@ export interface TreeNode readonly content: ((...a: never) => unknown) | PromiseLike> } -export interface TreeLeaf - extends Public> { +export interface TreeAbst + extends Public> { readonly basis: Base & MainModule readonly content: ((...a: never) => unknown) | PromiseLike> } @@ -264,15 +264,15 @@ class TreeNodeImpl { readonly parent: TreeNode | undefined readonly root: TreeNode readonly content: ((module: This) => Loaded) | PromiseLike> - readonly _leaf: TreeLeafImpl + readonly _abst: TreeAbstImpl readonly module: This & NodeMethod & InstProps constructor( relPath: Readonly | null, - arg: Pick, '_leaf' | 'content' | 'parent'> + arg: Pick, '_abst' | 'content' | 'parent'> ) { - const { _leaf, content, parent } = arg - const rootURL = parent?.root?.url ?? _leaf.rootURL ?? 'file:' + const { _abst, content, parent } = arg + const rootURL = parent?.root?.url ?? _abst.rootURL ?? 'file:' this.memo = parent?.memo ?? new Memo() this.moduleName = concatName(parent?.moduleName, relPath?.moduleName) this.stem = concatName(parent?.stem, relPath?.stem) @@ -282,8 +282,8 @@ class TreeNodeImpl { this.parent = parent this.root = parent?.root ?? this this.content = content - this._leaf = _leaf - const inst = createObject(_leaf.basis) + this._abst = _abst + const inst = createObject(_abst.basis) setTree(this, inst) const props: InstProps = { moduleName: this.moduleName.path, @@ -317,7 +317,7 @@ class TreeNodeImpl { } async main(c: Readonly): Promise { - const parent = this._leaf.findParent(c, this.module) + const parent = this._abst.findParent(c, this.module) if (parent !== this.parent) throw Error('parent page mismatch') if (c.moduleName.path !== this.moduleName.path) throw Error('name mismatch') const content = this.content @@ -344,12 +344,12 @@ class TreeNodeImpl { } } -type TreeLeafArg = Pick< - TreeLeafImpl, +type TreeAbstArg = Pick< + TreeAbstImpl, 'rootURL' | 'fileName' | 'basis' | 'content' | 'Base' > -export class TreeLeafImpl { +export class TreeAbstImpl { readonly rootURL: Readonly | undefined readonly fileName: FileName readonly content: ((module: This) => Loaded) | PromiseLike> @@ -361,7 +361,7 @@ export class TreeLeafImpl { TreeNodeImpl >() - constructor(arg: TreeLeafArg) { + constructor(arg: TreeAbstArg) { this.rootURL = arg.rootURL this.fileName = arg.fileName this.content = arg.content @@ -398,10 +398,10 @@ export class TreeLeafImpl { return isTreeNodeOf(tree, this.Base) ? tree : undefined } - getTreeLeaf(x: object): TreeLeaf | undefined { + getTreeAbst(x: object): TreeAbst | undefined { const tree = getTree(x) if (typeof tree !== 'object' || tree?.memo != null) return undefined - return tree != null && isTreeLeafOf(tree, this.Base) ? tree : undefined + return tree != null && isTreeAbstOf(tree, this.Base) ? tree : undefined } findParent( @@ -433,16 +433,16 @@ export class TreeLeafImpl { parent: TreeNode | undefined, relPath: Readonly | null ): TreeNodeImpl { - const arg = { _leaf: this, content: this.content, parent } + const arg = { _abst: this, content: this.content, parent } const tree = new TreeNodeImpl(relPath, arg) return tree } static decorate & NodeProps, Impl>( - arg: TreeLeafArg - ): TreeLeafImpl { + arg: TreeAbstArg + ): TreeAbstImpl { const node: This = Object.create(arg.basis) as typeof arg.basis - const tree = new TreeLeafImpl({ ...arg, basis: node }) + const tree = new TreeAbstImpl({ ...arg, basis: node }) setTree(tree, node) return tree } @@ -452,7 +452,7 @@ export class TreeLeafImpl { } static createDirectory(): Dir { - return new Indices, AssetLeaf>>() + return new Indices, AssetAbst>>() } declare readonly memo: undefined