@datalayer/core
Version:
[](https://datalayer.io)
154 lines (153 loc) • 4.92 kB
JavaScript
/*
* Copyright (c) 2023-2025 Datalayer, Inc.
* Distributed under the terms of the Modified BSD License.
*/
import * as notebooks from '../api/spacer/notebooks';
import { ItemDTO } from './ItemDTO';
import { ItemTypes } from '../client/constants';
import { validateJSON } from '../api/utils/validation';
/**
* Notebook domain model that extends the base Item class.
* Provides notebook-specific functionality for managing Jupyter notebooks.
*
* @example
* ```typescript
* const notebook = await sdk.createNotebook(formData);
* const kernelSpec = await notebook.getKernelSpec();
* ```
*/
export class NotebookDTO extends ItemDTO {
/**
* Create a Notebook instance.
*
* @param data - Notebook data from API
* @param sdk - SDK instance
*/
constructor(data, sdk) {
super(data, sdk);
}
// ========================================================================
// Abstract Method Implementations
// ========================================================================
/** Document type identifier. */
get type() {
this._checkDeleted();
return ItemTypes.NOTEBOOK;
}
/** The cached name of the notebook. */
get name() {
this._checkDeleted();
return (this._data.name_t ||
this._data.notebook_name_s ||
this._data.name ||
'');
}
/** The cached content. */
get content() {
this._checkDeleted();
if (!this._data.content && this._data.model_s) {
try {
return JSON.parse(this._data.model_s);
}
catch {
return this._data.model_s;
}
}
return this._data.content;
}
/** Get the current name from API. */
async getName() {
this._checkDeleted();
// For now, return cached value - implement API call if needed
return this.name;
}
/** Get when the notebook was last updated from API. */
async getUpdatedAt() {
this._checkDeleted();
const dateStr = this._data.updated_at || this._data.update_ts_dt;
if (!dateStr) {
throw new Error('No update timestamp available for notebook');
}
return new Date(dateStr);
}
/** Update the notebook. */
async update(name, description) {
// FIXME: check if both are needed, and use the existing values if only one provided
this._checkDeleted();
const token = this._sdk.getToken();
const spacerRunUrl = this._sdk.getSpacerRunUrl();
const updateData = {};
if (name !== undefined)
updateData.name = name;
if (description !== undefined)
updateData.description = description;
await notebooks.updateNotebook(token, this.uid, updateData, spacerRunUrl);
// FIXME: handle partial updates
return this;
}
// ========================================================================
// Notebook-specific Properties
// ========================================================================
/** File path within the space. */
get path() {
this._checkDeleted();
return this._data.path || '';
}
/** Version number. */
get version() {
this._checkDeleted();
return this._data.version || 0;
}
/** Notebook metadata. */
get metadata() {
this._checkDeleted();
return this._data.metadata || {};
}
/** Kernel specification (cached). */
get kernelSpec() {
this._checkDeleted();
return this._data.kernel_spec;
}
/** Description of the notebook. */
get description() {
this._checkDeleted();
return this._data.description_t || '';
}
/** Get the notebook extension. */
get extension() {
this._checkDeleted();
const ext = this._data.notebook_extension_s;
return ext ? (ext.startsWith('.') ? ext : `.${ext}`) : '.ipynb';
}
/**
* Get notebook data in camelCase format.
* Returns only the core fields that consumers need.
* This provides a stable interface regardless of API changes.
*
* @returns Core notebook data with camelCase properties
*/
toJSON() {
this._checkDeleted();
const obj = {
id: this.id,
uid: this.uid,
name: this.name,
description: this.description,
type: this.type,
extension: this.extension,
cdnUrl: this._data.cdn_url_s,
};
validateJSON(obj, 'Notebook');
return obj;
}
/**
* Get the raw notebook data exactly as received from the API.
* This preserves the original snake_case naming from the API response.
*
* @returns Raw notebook data from API
*/
rawData() {
this._checkDeleted();
return this._data;
}
}