Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: paginated relationships #9320

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
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
37 changes: 37 additions & 0 deletions packages/core-types/src/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,51 @@ export interface Graph {
destroy(): void;
}

/**
* Operations are granular instructions that can be applied to a cache to
* update its state.
*
* They are a bit like a PATCH but with greater context around the specific
* change being requested.
*
* @typedoc
*/
export interface Operation {
op: string;
}

/**
* Replace the current relationship remote state with an entirely
* new state.
*
* Effectively a PUT on the specific field.
*
* > [!Warning]
* > This operation behaves differently when used on a paginated collection.
* > In the paginated case, value is used to update the links and meta of the
* > relationshipObject.
* > If data is present, it is presumed that the data represents the data that
* > would be found on the `related` link in links, and will update the data
* > links, and meta on that page.
*
* @typedoc
*/
export interface UpdateRelationshipOperation {
op: 'updateRelationship';
/**
* The resource to operate on
* @typedoc
*/
record: StableRecordIdentifier;
/**
* The field on the resource that is being updated.
* @typedoc
*/
field: string;
/**
* The new value for the relationship.
* @typedoc
*/
value: SingleResourceRelationship | CollectionResourceRelationship;
}

Expand Down
54 changes: 41 additions & 13 deletions packages/diagnostic/server/bun/watch.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
import { watch } from 'fs';

export function addCloseHandler(cb) {
import { debug } from '../utils/debug.js';
export function addCloseHandler(cb, options) {
let executed = false;
const exit = options?.exit
? (signal) => {
debug(`Exiting with signal ${signal} in CloseHandler for ${options.label ?? '<unknown>'}`);
const code = typeof signal === 'number' ? signal : 1;
// eslint-disable-next-line n/no-process-exit
process.exit(code);
}
: (signal) => {
debug(`Ignoring signal ${signal} in CloseHandler for ${options.label ?? '<unknown>'}`);
};

process.on('SIGINT', () => {
if (executed) return;
process.on('SIGINT', (signal) => {
debug(`CloseHandler for ${options.label ?? '<unknown>'} Received SIGINT`);
if (executed) return exit(signal);
debug('Executing Close Handler for SIGINT');
executed = true;
cb();
exit(signal);
});

process.on('SIGTERM', () => {
if (executed) return;
process.on('SIGTERM', (signal) => {
debug(`CloseHandler for ${options.label ?? '<unknown>'} Received SIGTERM`);
if (executed) return exit(signal);
debug('Executing Close Handler for SIGTERM');
executed = true;
cb();
exit(signal);
});

process.on('SIGQUIT', () => {
if (executed) return;
process.on('SIGQUIT', (signal) => {
debug(`CloseHandler for ${options.label ?? '<unknown>'} Received SIGQUIT`);
if (executed) return exit(signal);
debug('Executing Close Handler for SIGQUIT');
executed = true;
cb();
exit(signal);
});

process.on('exit', () => {
if (executed) return;
process.on('exit', (signal) => {
debug(`CloseHandler for ${options.label ?? '<unknown>'} Received exit`);
if (executed) return exit(signal);
debug('Executing Close Handler for exit');
executed = true;
cb();
exit(signal);
});
}

Expand All @@ -33,7 +55,13 @@ export function watchAssets(directory, onAssetChange) {
onAssetChange(event, filename);
});

addCloseHandler(() => {
watcher.close();
});
addCloseHandler(
() => {
watcher.close();
},
{
label: 'watchAssets',
exit: false,
}
);
}
15 changes: 15 additions & 0 deletions packages/diagnostic/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { launchBrowsers } from './bun/launch-browser.js';
import { buildHandler } from './bun/socket-handler.js';
import { debug, error, print } from './utils/debug.js';
import { getPort } from './utils/port.js';
import { addCloseHandler } from './bun/watch.js';

/** @type {import('bun-types')} */
const isBun = typeof Bun !== 'undefined';
Expand Down Expand Up @@ -74,6 +75,20 @@ export default async function launch(config) {
debug(`Configured setup hook completed`);
}

addCloseHandler(
async () => {
if (config.cleanup) {
debug(`Running configured cleanup hook`);
await config.cleanup();
debug(`Configured cleanup hook completed`);
}
},
{
label: 'diagnostic server',
exit: true,
}
);

await launchBrowsers(config, state);
} catch (e) {
error(`Error: ${e?.message ?? e}`);
Expand Down
1 change: 1 addition & 0 deletions packages/diagnostic/src/-types/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface TestReport {
module: ModuleReport;
}
export interface ModuleReport {
id: string;
name: string;
start: PerformanceMark | null;
end: PerformanceMark | null;
Expand Down
1 change: 1 addition & 0 deletions packages/diagnostic/src/internals/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export async function runModule<TC extends TestContext>(

groupLogs() && console.groupCollapsed(module.name);
const moduleReport: ModuleReport = {
id: module.id,
name: module.moduleName,
start: null,
end: null,
Expand Down
36 changes: 32 additions & 4 deletions packages/diagnostic/src/reporters/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,20 +159,26 @@ export class DOMReporter implements Reporter {
`${iconForTestStatus(test)} ${labelForTestStatus(test)}`,
durationForTest(test),
`${test.module.name} > `,
`${test.name} (${test.result.diagnostics.length})`,
getURL(test.id),
`${test.name} (${countPassed(test.result.diagnostics)}/${test.result.diagnostics.length})`,
getTestURL(test.id),
getModuleURL(test.module.id),
]);
this.suite.results.set(test, tr);
});
this.suite.resultsList.appendChild(fragment);
}
}

function countPassed(diagnostics: DiagnosticReport[]) {
return diagnostics.filter((d) => d.passed).length;
}

function makeRow(tr: HTMLTableRowElement, cells: string[]) {
for (let i = 0; i < cells.length; i++) {
const cell = cells[i];
const td = document.createElement('td');
if (i === 3) {
td.className = 'warp-drive__diagnostic-test-name';
const strong = document.createElement('strong');
const text = document.createTextNode(cell);
strong.appendChild(text);
Expand All @@ -183,7 +189,12 @@ function makeRow(tr: HTMLTableRowElement, cells: string[]) {
} else if (i === 5) {
const a = document.createElement('a');
a.href = cell;
a.appendChild(document.createTextNode('rerun'));
a.appendChild(document.createTextNode('rerun test'));
td.appendChild(a);
} else if (i === 6) {
const a = document.createElement('a');
a.href = cell;
a.appendChild(document.createTextNode('rerun module'));
td.appendChild(a);
} else {
const text = document.createTextNode(cell);
Expand All @@ -193,11 +204,17 @@ function makeRow(tr: HTMLTableRowElement, cells: string[]) {
}
}

function getURL(id: string) {
function getTestURL(id: string) {
const currentURL = new URL(window.location.href);
currentURL.searchParams.set('t', id);
return currentURL.href;
}
function getModuleURL(id: string) {
const currentURL = new URL(window.location.href);
currentURL.searchParams.delete('t');
currentURL.searchParams.set('m', id);
return currentURL.href;
}

function durationForTest(test: TestReport) {
if (!test.start || !test.end) {
Expand Down Expand Up @@ -356,6 +373,17 @@ function renderSuite(element: DocumentFragment, suiteReport: SuiteReport): Suite
const resultsTable = document.createElement('table');
element.appendChild(resultsTable);

const colGroup = document.createElement('colgroup');
const colName = document.createElement('col');
colName.classList.add('warp-drive__diagnostic-test-name');
colGroup.appendChild(document.createElement('col')); // index
colGroup.appendChild(document.createElement('col')); // status
colGroup.appendChild(document.createElement('col')); // duration
colGroup.appendChild(colName); // name
colGroup.appendChild(document.createElement('col')); // rerun test
colGroup.appendChild(document.createElement('col')); // rerun module
resultsTable.appendChild(colGroup);

const resultsList = document.createElement('tbody');
resultsList.classList.add('diagnostic-results');
resultsTable.appendChild(resultsList);
Expand Down
32 changes: 30 additions & 2 deletions packages/diagnostic/src/styles/dom-reporter.css
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ body {
}

#warp-drive__diagnostic table {
table-layout: fixed;
box-sizing: border-box;
border-collapse: separate;
border-spacing: 0 0.1rem;
Expand All @@ -142,6 +143,18 @@ body {
#warp-drive__diagnostic table td {
box-sizing: border-box;
}
#warp-drive__diagnostic table col:nth-of-type(1) {
width: 2.5rem;
}
#warp-drive__diagnostic table col:nth-of-type(2) {
width: 2.5rem;
}
#warp-drive__diagnostic table col:nth-of-type(3) {
width: 2.5rem;
}
#warp-drive__diagnostic table .warp-drive__diagnostic-test-name {
width: calc(100vw - 16rem);
}

#warp-drive__diagnostic table tr {
box-sizing: border-box;
Expand All @@ -167,6 +180,8 @@ body {
#warp-drive__diagnostic table tr td:first-of-type {
border-radius: 0.1rem 0 0 0.1rem;
padding-left: 0.5rem;
font-size: 0.6em;
line-height: 0.6rem;
}
#warp-drive__diagnostic table tr td:last-of-type {
padding-right: 0.5rem;
Expand All @@ -178,6 +193,10 @@ body {
#warp-drive__diagnostic table tr:nth-last-of-type(odd) {
background: rgba(0, 0, 0, 0.8);
}
#warp-drive__diagnostic table tr.passed td:nth-child(2) {
font-size: 0.6em;
line-height: 0.6em;
}
#warp-drive__diagnostic table tr.passed td:nth-child(2) {
color: green;
}
Expand All @@ -192,6 +211,15 @@ body {
}
#warp-drive__diagnostic table td:nth-child(3) {
color: yellow;
font-size: 0.75em;
line-height: 0.75rem;
font-size: 0.6em;
line-height: 0.6rem;
}
#warp-drive__diagnostic table tr.passed td:nth-child(4) {
font-size: 0.85em;
line-height: 1.5em;
}
#warp-drive__diagnostic table tr.passed td:nth-child(5),
#warp-drive__diagnostic table tr.passed td:nth-child(6) {
font-size: 0.6em;
line-height: 0.6em;
}
1 change: 1 addition & 0 deletions packages/graph/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"scripts": {
"lint": "eslint . --quiet --cache --cache-strategy=content --report-unused-disable-directives",
"build:pkg": "vite build;",
"start": "vite build --watch;",
"prepack": "bun run build:pkg",
"sync-hardlinks": "bun run sync-dependencies-meta-injected"
},
Expand Down
6 changes: 3 additions & 3 deletions packages/graph/src/-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ import { DEBUG } from '@warp-drive/build-config/env';
import { getStore } from './-private/-utils';
import { Graph, Graphs } from './-private/graph';

export { isBelongsTo } from './-private/-utils';
export type { CollectionEdge } from './-private/edges/collection';
export type { ResourceEdge } from './-private/edges/resource';
export { isBelongsToEdge as isBelongsTo } from './-private/-utils';
export type { LegacyHasManyEdge as CollectionEdge } from './-private/edges/has-many';
export type { LegacyBelongsToEdge as ResourceEdge } from './-private/edges/belongs-to';
export type { ImplicitEdge } from './-private/edges/implicit';
export type { GraphEdge } from './-private/graph';
export type { UpgradedMeta } from './-private/-edge-definition';
Expand Down
Loading