Skip to content

OBEE-39: implement table runtime and backing for createInstance factory - #1413

Open
tslil-topos wants to merge 1 commit into
mainfrom
tslil/instance_types_runtime
Open

OBEE-39: implement table runtime and backing for createInstance factory#1413
tslil-topos wants to merge 1 commit into
mainfrom
tslil/instance_types_runtime

Conversation

@tslil-topos

Copy link
Copy Markdown
Collaborator

tests will be included in the last change stacked on this

This is an absolute grind of a change. There are simply twelve quadrillion things that have to happen to make things like changing rows or adjusting tables work correctly.

The basic pattern is visible in instance-runtime.ts :

async function withValidatedSchema<
    Handle,
    S extends Shape,
    T,
    E extends ReadonlyArray<Issue> = ReadonlyArray<Issue>,
>(
    schema: Notebook<S, ModelDocument>,
    operation: (schemaModel: DblModel) => Result<T, E>,
): Promise<Result<T, E>>

is used to perform the steps of obtaining a dblmodel (or erroring if the schema doesn't validate), learning about the table structure, and finally running the operation (which might itself fail in a way at least as exciting as ReadonlyArray). So this is what is contained in the factory functions that will (in a later change) back the Instance factory: createTablesMethod, createGetMethod, createAddRowManyMethod, etc.

Then there's the elephant: table-methods.ts. The basic premise for all of these is to permissively apply everything that makes sense, and report everything that failed. Thus an Ok is only possible if went well. The only kinds of failures that are important here are addressing failures: mentioning a table that doesn't exist, mentioning a row that doesn't exist. Type issues, missing entries, bad links, and so on are all semantic checks that will be caught by validation passes.

@tslil-topos tslil-topos self-assigned this Aug 21, 2026
@tslil-topos tslil-topos added enhancement New feature or request frontend TypeScript frontend and Rust-wasm integrations labels Aug 21, 2026
@github-actions

Copy link
Copy Markdown

Notion Integration

@tslil-topos
tslil-topos force-pushed the tslil/instance_types_runtime branch from 4e5cb13 to c8e5a9f Compare August 21, 2026 13:04
@tslil-topos
tslil-topos force-pushed the tslil/instance_types_runtime branch from c8e5a9f to 3fa7ebb Compare August 21, 2026 13:18
Comment on lines +397 to +415
function orderedRowIds(table: Readonly<DocumentTypes.Table> | undefined): string[] {
if (table === undefined) {
return [];
}
const seen = new Set<string>();
const ordered: string[] = [];
for (const id of table.rowOrder ?? []) {
if (table.rows[id] !== undefined && !seen.has(id)) {
seen.add(id);
ordered.push(id);
}
}
for (const id of Object.keys(table.rows)) {
if (!seen.has(id)) {
ordered.push(id);
}
}
return ordered;
}

@kasbah kasbah Aug 21, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is being defensive in the wrong place and also papers over any structural issues if they are there. It speaks to the overall flaw I see in this implementation: we should parse our doc into a structure where we know:

  • table.rowOrder is not undefined
  • table.rowOrder has all the keys of table.rows and no more
  • any other invariants we want to hold for the JSON structure

We should then be able to use table.rowOrder directly instead of this function. In general it should allow us to split up the process into something like "parse-doc.ts" and then "table-methods.ts" that operate on the parsed doc.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think flaw is a strong word. The comments and PR text explain the approach taken: all actions are maximally permissive. If the instance is in a bad state we should still be able to take all actions that we are interested in. It's up to users of this api to ensure that valid passes, and all of these functions share the guarantee: if the schema and instance are valid then all operations are faithful and exhibit all data.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what word to use but I disagree with the approach exhibited by this defensive error swallowing code and with things like:

Every update that fails to address is skipped and the rest are still applied.

Where "skipped" means "silently skipped"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you could weigh in on this one @epatters since tslil and I seem to have very different views on this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what word to use but I disagree with the approach exhibited by this defensive error swallowing code and with things like:

Every update that fails to address is skipped and the rest are still applied.

Where "skipped" means "silently skipped"

it does not, did you see the preceding sentence or the code paths Only addressing failures are reported as issues.?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, looks good on re-reading. You pushed some updates to comments?

I still think that the function orderedRowIds is not the right approach. I'll open a PR for how I think it can be improved.

@tslil-topos
tslil-topos force-pushed the tslil/instance_types_runtime branch from 3fa7ebb to d917c95 Compare August 21, 2026 14:58
@tslil-topos
tslil-topos requested a review from kasbah August 24, 2026 12:46
@tslil-topos

Copy link
Copy Markdown
Collaborator Author

@kasbah please approve this change so that we can proceed to the difficult and time-consuming integration work that lives on-top of this stack. If we want to revisit this approach, assuming that this doesn't break fundamental UI operations (would be happy to hear a case that the split of error reporting between addressing issues on operations, all issues on validate is difficult for consumers), then we can do so after the deadline and we could open an issue now to remind us to do so once there is more time.

Base automatically changed from tslil/instance_types to main August 24, 2026 13:24
*tests will be included in the last change stacked on this*

This is an absolute grind of a change. There are simply twelve quadrillion things that have to happen to make things like changing rows or adjusting tables work correctly.

The basic pattern is visible in instance-runtime.ts :

```typescript
async function withValidatedSchema<
    Handle,
    S extends Shape,
    T,
    E extends ReadonlyArray<Issue> = ReadonlyArray<Issue>,
>(
    schema: Notebook<S, ModelDocument>,
    operation: (schemaModel: DblModel) => Result<T, E>,
): Promise<Result<T, E>>
```

is used to perform the steps of obtaining a dblmodel (or erroring if the schema doesn't validate), learning about the table structure, and finally running the operation (which might itself fail in a way at least as exciting as ReadonlyArray<Issue>). So this is what is contained in the factory functions that will (in a later change) back the Instance factory: `createTablesMethod`, `createGetMethod`, `createAddRowManyMethod`, etc.

Then there's the elephant: table-methods.ts. The basic premise for all of these is to permissively apply everything that makes sense, and report everything that failed. Thus an `Ok` is only possible if went well. The only kinds of failures that are important here are addressing failures: mentioning a table that doesn't exist, mentioning a row that doesn't exist. Type issues, missing entries, bad links, and so on are all semantic checks that will be caught by validation passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request frontend TypeScript frontend and Rust-wasm integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants