Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/libro-code-cell/src/code-cell-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export class LibroCodeCellView extends LibroEditableExecutableCellView {
cell: this,
toJSON: () => ({ cellId: this.id }),
})
.then(async (outputArea) => {
.then(async (outputArea: LibroOutputArea) => {
this.outputArea = outputArea;
const output = this.outputs;
if (isOutput(output)) {
Expand Down
2 changes: 2 additions & 0 deletions packages/libro-core/src/cell/libro-cell-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,12 @@ export class LibroCellView extends BaseView implements CellView {
}

disposed = false;

override dispose() {
this.toDispose.dispose();
super.dispose();
}

toJSON(): LibroCell {
const meta = { ...(this.model.toJSON() as LibroCell) };
const modelContribution = this.cellService.findModelProvider(this.model.options);
Expand Down
10 changes: 9 additions & 1 deletion packages/libro-core/src/libro-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,9 @@ export class LibroView extends BaseView implements NotebookView {
};

deleteCell = (cell: CellView) => {
if (this.disposed) {
return;
}
if (this.libroViewTracker.isEnabledSpmReporter && cell.model.id) {
const id = cell.model.id + this.id;
const libroTracker = this.libroViewTracker.getOrCreateTrackers({
Expand Down Expand Up @@ -1375,10 +1378,15 @@ export class LibroView extends BaseView implements NotebookView {

override dispose() {
if (!this.disposed) {
this.disposed = true;
this.libroService.deleteLibroViewFromCache(this);
this.toDispose.dispose();
this.model.cells.forEach((cell) => {
if (!cell.disposed) {
cell.dispose();
}
});
}
this.disposed = true;
super.dispose();
}

Expand Down
24 changes: 19 additions & 5 deletions packages/libro-core/src/output/output-model.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import type { IOutput, JSONObject, PartialJSONObject } from '@difizen/libro-common';
import { BaseView, Emitter, prop, view, ViewOption } from '@difizen/libro-common/app';
import { inject, transient } from '@difizen/libro-common/app';
import {
BaseView,
Emitter,
prop,
view,
ViewOption,
DisposableCollection,
inject,
transient,
} from '@difizen/libro-common/app';
import type { FC } from 'react';
import { v4 } from 'uuid';

Expand Down Expand Up @@ -33,6 +41,8 @@ export class LibroOutputView extends BaseView implements BaseOutputView {
@prop()
data: JSONObject;

protected override toDispose = new DisposableCollection();

onUpdateEmitter = new Emitter<void>();

get onUpdate() {
Expand All @@ -51,14 +61,18 @@ export class LibroOutputView extends BaseView implements BaseOutputView {
this.type = 'libro-default-output';
this.data = {};
this.metadata = {};
this.onUpdate(() => {
this.cell.parent.model.onChange?.();
});
this.toDispose.push(this.onUpdateEmitter);
this.toDispose.push(
this.onUpdate(() => {
this.cell.parent.model.onChange?.();
}),
);
}

render: FC<{ output: BaseOutputView }> = LibroOutputModelRender;

override dispose() {
this.toDispose.dispose();
super.dispose();
}
toJSON() {
Expand Down
122 changes: 66 additions & 56 deletions packages/libro-jupyter/src/output/libro-jupyter-outputarea.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import type * as nbformat from '@difizen/libro-common';
import {
inject,
transient,
view,
ViewOption,
DisposableCollection,
} from '@difizen/libro-common/app';
import type {
LibroEditableExecutableCellView,
ExecutableCellModel,
Expand All @@ -15,13 +22,13 @@ import {
isStreamMsg,
isUpdateDisplayDataMsg,
} from '@difizen/libro-kernel';
import { inject, transient, view, ViewOption } from '@difizen/libro-common/app';

@transient()
@view('libro-output-area')
export class LibroJupyterOutputArea extends LibroOutputArea {
declare cell: LibroEditableExecutableCellView;
protected displayIdMap = new Map<string, number[]>();
protected override toDispose = new DisposableCollection();

constructor(@inject(ViewOption) option: IOutputAreaOption) {
super(option);
Expand All @@ -30,69 +37,72 @@ export class LibroJupyterOutputArea extends LibroOutputArea {

handleMsg() {
const cellModel = this.cell.model as ExecutableCellModel;
cellModel.msgChangeEmitter.event((msg) => {
const transientMsg = (msg.content.transient || {}) as nbformat.JSONObject;
const displayId = transientMsg['display_id'] as string;
if (isExecuteInputMsg(msg)) {
cellModel.executeCount = msg.content.execution_count;
}
if (
isDisplayDataMsg(msg) ||
isStreamMsg(msg) ||
isErrorMsg(msg) ||
isExecuteResultMsg(msg)
) {
const output: nbformat.IOutput = {
...msg.content,
output_type: msg.header.msg_type,
};
this.add(output);
}
if (isUpdateDisplayDataMsg(msg)) {
const output = { ...msg.content, output_type: 'display_data' };
const targets = this.displayIdMap.get(displayId);
if (targets) {
for (const index of targets) {
this.set(index, output);
}
this.toDispose.push(
cellModel.msgChangeEmitter.event((msg: any) => {
const transientMsg = (msg.content.transient || {}) as nbformat.JSONObject;
const displayId = transientMsg['display_id'] as string;
if (isExecuteInputMsg(msg)) {
cellModel.executeCount = msg.content.execution_count;
}
}
if (displayId && isDisplayDataMsg(msg)) {
const targets = this.displayIdMap.get(displayId) || [];
targets.push(this.outputs.length);
this.displayIdMap.set(displayId, targets);
}
//Handle an execute reply message.
if (isExecuteReplyMsg(msg)) {
const content = msg.content;
if (content.status !== 'ok') {
return;
if (
isDisplayDataMsg(msg) ||
isStreamMsg(msg) ||
isErrorMsg(msg) ||
isExecuteResultMsg(msg)
) {
const output: nbformat.IOutput = {
...msg.content,
output_type: msg.header.msg_type,
};
this.add(output);
}
if (isUpdateDisplayDataMsg(msg)) {
const output = { ...msg.content, output_type: 'display_data' };
const targets = this.displayIdMap.get(displayId);
if (targets) {
for (const index of targets) {
this.set(index, output);
}
}
}
const payload = content && content.payload;
if (!payload || !payload.length) {
return;
if (displayId && isDisplayDataMsg(msg)) {
const targets = this.displayIdMap.get(displayId) || [];
targets.push(this.outputs.length);
this.displayIdMap.set(displayId, targets);
}
const pages = payload.filter((i: any) => i.source === 'page');
if (!pages.length) {
return;
//Handle an execute reply message.
if (isExecuteReplyMsg(msg)) {
const content = msg.content;
if (content.status !== 'ok') {
return;
}
const payload = content && content.payload;
if (!payload || !payload.length) {
return;
}
const pages = payload.filter((i: any) => i.source === 'page');
if (!pages.length) {
return;
}
const page = JSON.parse(JSON.stringify(pages[0]));
const output: nbformat.IOutput = {
output_type: 'display_data',
data: page.data as nbformat.IMimeBundle,
metadata: {},
};
this.add(output);
}
const page = JSON.parse(JSON.stringify(pages[0]));
const output: nbformat.IOutput = {
output_type: 'display_data',
data: page.data as nbformat.IMimeBundle,
metadata: {},
};
this.add(output);
}

if (isClearOutputMsg(msg)) {
const wait = msg.content.wait;
this.clear(wait);
}
});
if (isClearOutputMsg(msg)) {
const wait = msg.content.wait;
this.clear(wait);
}
}),
);
}

override dispose(): void {
this.toDispose.dispose();
this.displayIdMap.clear();
super.dispose();
}
Expand Down
2 changes: 1 addition & 1 deletion packages/libro-prompt-cell/src/prompt-cell-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ export class LibroPromptCellView extends LibroEditableExecutableCellView {
cell: this,
toJSON: () => ({ cellId: this.id }),
})
.then(async (outputArea) => {
.then(async (outputArea: LibroOutputArea) => {
this.outputArea = outputArea;
const output = this.outputs;
if (isOutput(output)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/libro-sql-cell/src/libro-sql-cell-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ export class LibroSqlCellView extends LibroEditableExecutableCellView {
cell: this,
toJSON: () => ({ cellId: this.id }),
})
.then(async (outputArea) => {
.then(async (outputArea: LibroOutputArea) => {
this.outputArea = outputArea;
const output = this.outputs;
if (isOutput(output)) {
Expand Down
Loading