Skip to content

Commit

Permalink
feat(types): Make explicit widget_manager interface (#670)
Browse files Browse the repository at this point in the history
* feat(types): Make explicit widget_manager interface

* chore(anywidget): Make @anywidget/types a dev dependency

* chore: Resync packages
  • Loading branch information
manzt authored Aug 29, 2024
1 parent 6fc3226 commit 9c10efe
Show file tree
Hide file tree
Showing 7 changed files with 1,610 additions and 2,591 deletions.
10 changes: 10 additions & 0 deletions .changeset/big-guests-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@anywidget/types": minor
---

Makes explicit WidgetManager interface

Drops `@jupyter-widgets/base` as a dependency and instead makes an explicit
interface for `AnyModel.widget_manager`. Right now we only support
`widget_manager.get_model`, so having the other methods on the interface was
misleading (leading to issues around `.create_view` not being supported).
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
"typescript": "^5.5.4",
"vitest": "^2.0.5"
},
"packageManager": "pnpm@9.4.0"
"packageManager": "pnpm@9.9.0"
}
2 changes: 1 addition & 1 deletion packages/anywidget/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
"build": "node scripts/build.cjs"
},
"dependencies": {
"@anywidget/types": "workspace:~",
"@jupyter-widgets/base": "^6",
"@lukeed/uuid": "^2.0.1",
"solid-js": "^1.8.20"
},
"devDependencies": {
"@anywidget/types": "workspace:^",
"@jupyter-widgets/base-manager": "^1.0.11"
},
"jupyterlab": {
Expand Down
17 changes: 13 additions & 4 deletions packages/anywidget/src/widget.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import * as uuid from "@lukeed/uuid";
import * as solid from "solid-js";

/**
* @template T
* @typedef {T | PromiseLike<T>} Awaitable
*/

/**
* @typedef AnyWidget
* @prop initialize {import("@anywidget/types").Initialize}
Expand All @@ -14,7 +19,7 @@ import * as solid from "solid-js";
*/

/**
* @param {any} condition
* @param {unknown} condition
* @param {string} message
* @returns {asserts condition}
*/
Expand Down Expand Up @@ -192,12 +197,16 @@ function model_proxy(model, context) {
off(name, callback) {
model.off(name, callback, context);
},
// @ts-expect-error - the widget_manager type is wider than what
// we want to expose to developers.
// In a future version, we will expose a more limited API but
// that can wait for a minor version bump.
widget_manager: model.widget_manager,
};
}

/**
* @param {void | (() => import('vitest').Awaitable<void>)} fn
* @param {void | (() => Awaitable<void>)} fn
* @param {string} kind
*/
async function safe_cleanup(fn, kind) {
Expand Down Expand Up @@ -320,7 +329,7 @@ class Runtime {
console.debug(`[anywidget] esm hot updated: ${id}`);
setEsm(model.get("_esm"));
});
/** @type {void | (() => import("vitest").Awaitable<void>)} */
/** @type {void | (() => Awaitable<void>)} */
let cleanup;
this.#widget_result = solid.createResource(esm, async (update) => {
await safe_cleanup(cleanup, "initialize");
Expand Down Expand Up @@ -355,7 +364,7 @@ class Runtime {
async create_view(view) {
let model = view.model;
let disposer = solid.createRoot((dispose) => {
/** @type {void | (() => import("vitest").Awaitable<void>)} */
/** @type {void | (() => Awaitable<void>)} */
let cleanup;
let resource = solid.createResource(
this.#widget_result,
Expand Down
11 changes: 8 additions & 3 deletions packages/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { IWidgetManager } from "@jupyter-widgets/base";

type Awaitable<T> = T | Promise<T>;
type ObjectHash = Record<string, any>;
type ChangeEventHandler<Payload> = (_: unknown, value: Payload) => void;
Expand All @@ -13,6 +11,13 @@ type EventHandler = (...args: any[]) => void;
*/
type LiteralUnion<T, U = string> = T | (U & {});

interface WidgetManager {
/**
* Get a promise for a model by model id.
*/
get_model<T extends ObjectHash>(model_id: string): Promise<AnyModel<T>>;
}

export interface AnyModel<T extends ObjectHash = ObjectHash> {
get<K extends keyof T>(key: K): T[K];
set<K extends keyof T>(key: K, value: T[K]): void;
Expand Down Expand Up @@ -41,7 +46,7 @@ export interface AnyModel<T extends ObjectHash = ObjectHash> {
callbacks?: any,
buffers?: ArrayBuffer[] | ArrayBufferView[],
): void;
widget_manager: IWidgetManager;
widget_manager: WidgetManager;
}

export type Experimental = {
Expand Down
3 changes: 0 additions & 3 deletions packages/types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
"import": "./index.ts"
}
},
"dependencies": {
"@jupyter-widgets/base": "^6.0.8"
},
"publishConfig": {
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
Loading

0 comments on commit 9c10efe

Please sign in to comment.