Skip to content

Commit

Permalink
Add categories to API docs
Browse files Browse the repository at this point in the history
  • Loading branch information
pjeby committed May 20, 2024
1 parent 2b14de7 commit 42b2a01
Show file tree
Hide file tree
Showing 24 changed files with 173 additions and 10 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@types/node": "16",
"cross-cat": "^1.0.0",
"esbuild-plugin-inline-import": "^1.0.4",
"onchange": "^7.1.0",
"sass": "^1.76.0",
"tsup": "^8.0.2",
"tsx": "^4.10.0",
Expand All @@ -41,6 +42,7 @@
},
"scripts": {
"docs": "tsx typedoc/run.mts",
"watch-docs": "onchange -i --kill \"*.md\" \"guides/**/*.md\" \"typedoc.config.*\" \"typedoc/*\" -- tsx typedoc/run.mts --watch",
"prepare": "tsup && cross-cat src/augments.d.ts >>dist/index.d.ts"
}
}
27 changes: 27 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/augments.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ declare module "obsidian" {
containerEl: HTMLDivElement;
}
interface Component {
/** @internal */
_loaded: boolean
}
interface App {
Expand Down
20 changes: 17 additions & 3 deletions src/cleanups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { untracked } from "@preact/signals-core";
import { defer } from "./defer.ts";

type Nothing = undefined | null | void;
/** @category Targeted for Removal */
export type Cleanup = () => unknown;
/** @category Targeted for Removal */
export type OptionalCleanup = Cleanup | Nothing;
type PlainFunction = (this: null, ...args: any[]) => any;

Expand All @@ -19,6 +21,8 @@ type PlainFunction = (this: null, ...args: any[]) => any;
* savepoint, or throw an error if there is none. (You can use
* `savepoint.active` to check if there is a currently active
* savepoint, or make one active using its `.run()` method.)
*
* @category Targeted for Removal
*/
interface savepoint extends ActiveSavePoint {
/** Is there a currently active savepoint? */
Expand All @@ -37,6 +41,7 @@ interface savepoint extends ActiveSavePoint {
new(action?: () => OptionalCleanup): SavePoint;
}

/** @category Targeted for Removal */
export interface ActiveSavePoint {
/**
* Add zero or more cleanup callbacks to be run when the savepoint is rolled
Expand Down Expand Up @@ -80,6 +85,7 @@ export interface ActiveSavePoint {
link(subtask: SavePoint, stop?: Cleanup): SavePoint
}

/** @category Targeted for Removal */
export interface SavePoint extends ActiveSavePoint {
/**
* Call all the added cleanup callbacks; if any throw exceptions, they're
Expand All @@ -106,6 +112,7 @@ function getCurrent() {
throw new Error("no savepoint is currently active");
}

/** @category Targeted for Removal */
export let savepoint: savepoint & {
/** @internal - used for effect scoping */
wrapEffect(action: () => OptionalCleanup): () => OptionalCleanup
Expand Down Expand Up @@ -190,13 +197,13 @@ export let savepoint: savepoint & {
}


/** @deprecated - use `savepoint.active` instead */
/** @deprecated - use `savepoint.active` instead @category Targeted for Removal */
export function canCleanup() { return savepoint.active; }

/** @deprecated - use `savepoint.add()` instead */
/** @deprecated - use `savepoint.add()` instead @category Targeted for Removal */
export function cleanup(...cleanups: OptionalCleanup[]) { savepoint.add(...cleanups); }

/** @deprecated - use `new savepoint(action).rollback` */
/** @deprecated - use `new savepoint(action).rollback` @category Targeted for Removal */
export function withCleanup(action: () => OptionalCleanup): Cleanup;
export function withCleanup(action: () => OptionalCleanup, optional: false): Cleanup;
export function withCleanup(action: () => OptionalCleanup, optional: true): OptionalCleanup;
Expand All @@ -206,7 +213,10 @@ export function withCleanup(action: () => OptionalCleanup, optional?: boolean):

var currentJob: Job<any>;

/** @category Targeted for Removal */
export type JobGenerator<T=void> = Generator<void,T,any>

/** @category Targeted for Removal */
export type Awaiting<T> = Generator<void, T, any>;

/**
Expand All @@ -225,6 +235,8 @@ export type Awaiting<T> = Generator<void, T, any>;
* order to correctly infer types inside the generator function.
*
* @returns A new Job instance, or the current job (which may be undefined).
*
* @category Targeted for Removal
*/
export function job<R,T>(thisObj: T, fn: (this:T) => JobGenerator<R>): Job<R>
export function job<R>(fn: (this:void) => JobGenerator<R>): Job<R>
Expand All @@ -240,11 +252,13 @@ export function job<R>(

/**
* @deprecated Use `job(thisArg, function*(this) { ... })` instead.
* @category Targeted for Removal
*/
export function spawn<T,R>(thisArg: T, gf: (this: T) => JobGenerator<R>): Job<R> {
return job(thisArg, gf);
}

/** @category Targeted for Removal */
export interface Job<T> extends Promise<T> {
next(v?: any): void;
return(v?: T): void;
Expand Down
2 changes: 2 additions & 0 deletions src/defer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const defer: (cb: () => any) => void = typeof queueMicrotask === "functio
* a promise for the result of that callback. The callback will not be run until after all previous callbacks
* have run. If no callback is supplied to the queue, the promise returned is for the most-recently-executed
* callback.
*
* @category Targeted for Removal
*/
export function taskQueue() {
let last: Promise<any> = Promise.resolve();
Expand Down
2 changes: 2 additions & 0 deletions src/deferred.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/** @category Targeted for Removal */
export interface Deferred<T> {
resolve: (value: T | PromiseLike<T>) => void
reject: (reason?: any) => void
promise: Promise<T>
}

/** @category Targeted for Removal */
export function deferred<T>(): Deferred<T> {
let resolve: Deferred<T>["resolve"];
let reject: Deferred<T>["reject"];
Expand Down
5 changes: 5 additions & 0 deletions src/eventful.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ declare module "wonka" {

const Pull = 0 as Upstream.Pull, Close = 1 as Upstream.Close, Start = 0 as SignalKind.Start, End = 0 as SignalKind.End;

/** @category Targeted for Removal */
export type Waitable<T> = (() => T) | Source<T> | Promise<T> | PromiseLike<T>

/**
Expand Down Expand Up @@ -43,6 +44,8 @@ export type Waitable<T> = (() => T) | Source<T> | Promise<T> | PromiseLike<T>
* than providing a value, and this callback is supplied, it is invoked with the
* error. If this callback is not provided, the error will go unhandled or
* become an unhandled promise rejection.
*
* @category Targeted for Removal
*/
export function when<T>(source: Waitable<T>, sink: (value: T) => OptionalCleanup, onErr?: (e: any) => void): () => void {
var outer = savepoint.active && savepoint.subtask(unsub), inner = new savepoint();
Expand Down Expand Up @@ -105,6 +108,8 @@ export function isPromiseLike<T>(obj: any): obj is PromiseLike<any> | Promise<T>
*
* @returns The triggered event, promise resolution, or signal value. An error
* is thrown if the promise rejects or the event stream is closed.
*
* @category Targeted for Removal
*/
export function *until<T>(source: Waitable<T>): Awaiting<T> {
var self = job(), upstream: UpstreamFn, close: () => void;
Expand Down
2 changes: 2 additions & 0 deletions src/indexing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function recordEntry(k: any, v: any) {
((toAdd || (toAdd = freeMaps.pop() || new Map)).get(k) || setMap(toAdd, k, freeSets.pop() || new Set)).add(v);
}

/** @category Indexing */
export abstract class AbstactIndexer<T extends Record<string,any>, I extends object> extends Component {
protected indices = new Map<keyof T, Map<any, Set<I>>>();
protected version = signal(0);
Expand Down Expand Up @@ -135,6 +136,7 @@ export abstract class AbstactIndexer<T extends Record<string,any>, I extends obj
}
}

/** @category Indexing */
export abstract class NoteMetaIndexer<T extends Record<string,any>> extends AbstactIndexer<T, o.TFile> {
use = use.service(this);
onload() {
Expand Down
15 changes: 12 additions & 3 deletions src/layout/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,23 @@ import { defer } from "../defer.ts";
import { app, Useful, Service } from "../services.ts";
import { cloneValue } from "../clone-value.ts";

/** An object with layout-stored settings (Workspace, WorkspaceItem, etc.) */
/**
* An object with layout-stored settings (Workspace, WorkspaceItem, etc.)
*
* @category Layout and Workspaces
*/
interface HasLayoutSettings {
[layoutProps]?: any
}

/** Things that can have layout-stored settings */
/**
* Things that can have layout-stored settings
*
* @category Layout and Workspaces
*/
export type LayoutItem = o.WorkspaceItem | o.Workspace;

/** @category Layout and Workspaces */
export class LayoutSetting<V extends any, T extends LayoutItem> {

store: LayoutStorage;
Expand Down Expand Up @@ -60,7 +69,7 @@ export class LayoutSetting<V extends any, T extends LayoutItem> {
}
}


/** @category Layout and Workspaces */
export class LayoutStorage extends Service {

get<V extends any>(from: LayoutItem, key: string, defaultValue?: V): V {
Expand Down
3 changes: 3 additions & 0 deletions src/layout/walk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { obsidian as o } from "../obsidian.ts";
import { LayoutItem } from "./settings.ts";
import { app } from "../services.ts";

/** @category Layout and Workspaces */
export function isLeafAttached(leaf: o.WorkspaceLeaf) {
const ws = app.workspace, root = leaf?.getRoot();
switch (root) {
Expand All @@ -27,6 +28,8 @@ type layoutVisitor = (item: LayoutItem) => boolean | void;
* visitor function returned true at any point in the traversal, false otherwise.
*
* @param visitor Callback taking a Workspace or WorkspaceItem, can return true to stop the traversal
*
* @category Layout and Workspaces
*/
export function walkLayout(visitor: layoutVisitor): boolean;

Expand Down
12 changes: 12 additions & 0 deletions src/layout/window-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { around } from "monkey-around";
import { isLeafAttached } from "./walk.ts";
import { Component } from "obsidian";

/** @category Window Management */
export type PWCFactory<C extends PerWindowComponent> = {
new (use: Context, item: o.WorkspaceContainer): C
onload(use: Context): void;
Expand Down Expand Up @@ -34,6 +35,8 @@ export type PWCFactory<C extends PerWindowComponent> = {
* If you want your components to be created lazily only on-demand instead of eagerly
* and automatically, you can leave off the `.watch()` call, e.g.
* `titleWidget = this.use(TitleWidget)` instead.
*
* @category Window Management
*/
export class PerWindowComponent extends Component {

Expand All @@ -54,6 +57,8 @@ export class PerWindowComponent extends Component {

/**
* Manage per-window components
*
* @category Window Management
*/
export class WindowManager<T extends PerWindowComponent> extends Service {

Expand Down Expand Up @@ -185,29 +190,35 @@ export class WindowManager<T extends PerWindowComponent> extends Service {
}
}

/** @category Window Management */
export function allContainers(): o.WorkspaceContainer[] {
return [app.workspace.rootSplit].concat(app.workspace.floatingSplit.children);
}

/** @category Window Management */
export function allWindows() {
return allContainers().map(c => c.win);
}

/** @category Window Management */
export function numWindows() {
return 1 + (app.workspace.floatingSplit?.children.length ?? 0);
}

/** @category Window Management */
export function windowEvent(cond: (win: Window, evt: Event) => boolean): Event {
for (const win of allWindows()) {
if (win.event && cond(win, win.event)) return win.event;
}
}

/** @category Window Management */
export function windowForDom(el: Node) {
// Backward compat to 0.14, which has no .win on nodes; can just use el.win on 0.15.6+
return el.win || (el.ownerDocument || <Document>el).defaultView || window;
}

/** @category Window Management */
export function containerForWindow(win: Window): o.WorkspaceContainer {
if (win === window) return app.workspace.rootSplit;
const {floatingSplit} = app.workspace;
Expand All @@ -216,6 +227,7 @@ export function containerForWindow(win: Window): o.WorkspaceContainer {
}
}

/** @category Window Management */
export function focusedContainer(): o.WorkspaceContainer | undefined {
return allContainers().filter(c => c.win.document.hasFocus()).pop();
}
3 changes: 3 additions & 0 deletions src/plugin-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ import { computed, effect, signal } from "./signify.ts";
* @param once (Optional) A function to call with settings once, as soon as they're available
*
* @returns A {@link SettingsService} you can use to `.update()` the settings
*
* @category Settings Management
*/
export function useSettings<T>(
owner: o.Component & Partial<Useful>,
Expand All @@ -61,6 +63,7 @@ export function useSettings<T>(
return svc;
}

/** @category Settings Management */
export class SettingsService<T extends {}> extends Service {
private plugin = this.use(o.Plugin);
private queue = taskQueue();
Expand Down
Loading

0 comments on commit 42b2a01

Please sign in to comment.