Skip to content
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
2 changes: 1 addition & 1 deletion core
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
rest: true
graphqlSchema:
files: '*.graphql'
jsResource:
files: resources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Readable } from 'node:stream';
import { threadId } from 'node:worker_threads';

const originUrl = process.env.HARPER_TEST_ORIGIN_URL;
// Keep payloads above core's 8 KiB inline-storage threshold.
const payloadSize = 16 * 1024;

function payloadFor(token) {
const bytes = Buffer.alloc(payloadSize, 0x2e);
bytes.write(token);
return createBlob(Readable.from(bytes));
}

tables.PairRecord.sourcedFrom({
async get(id) {
const response = await fetch(`${originUrl}/resolve`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id, node: server.hostname, threadId }),
});
if (!response.ok) throw new Error(`Pairing origin returned ${response.status}: ${await response.text()}`);
const resolved = await response.json();
return {
id,
token: resolved.token,
sourceNode: server.hostname,
sourceThread: threadId,
payload: payloadFor(resolved.token),
};
},
});

function describeRecord(record) {
if (!record?.payload) return null;
return record.payload.bytes().then((bytes) => ({
id: record.id,
token: record.token,
sourceNode: record.sourceNode,
sourceThread: record.sourceThread,
payloadToken: bytes.subarray(0, Buffer.byteLength(record.token)).toString(),
}));
}
Comment on lines +33 to +42

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Ensure appropriate null/undefined checks exist before accessing properties or calling methods on potentially nullable references like record.payload to prevent runtime TypeErrors.

Suggested change
function describeRecord(record) {
if (!record) return null;
return record.payload.bytes().then((bytes) => ({
id: record.id,
token: record.token,
sourceNode: record.sourceNode,
sourceThread: record.sourceThread,
payloadToken: bytes.subarray(0, Buffer.byteLength(record.token)).toString(),
}));
}
function describeRecord(record) {
if (!record || !record.payload) return null;
return record.payload.bytes().then((bytes) => ({
id: record.id,
token: record.token,
sourceNode: record.sourceNode,
sourceThread: record.sourceThread,
payloadToken: bytes.subarray(0, Buffer.byteLength(record.token)).toString(),
}));
}


export class PairPointProbe extends tables.PairRecord {
static async get(target) {
const record = await super.get(target);
let raw;
for (const entry of tables.PairRecord.primaryStore.getRange({ start: null, versions: true, snapshot: false })) {
if (entry.key === target.id) {
raw = { version: entry.version, nodeId: entry.nodeId, record: await describeRecord(entry.value) };
break;
}
}
return { node: server.hostname, threadId, record: await describeRecord(record), raw };
}
}

export class PairScanProbe extends Resource {
static loadAsInstance = false;

async get(target) {
target.checkPermission = false;
for (const entry of tables.PairRecord.primaryStore.getRange({ start: null, versions: true, snapshot: false })) {
if (entry.key === target.id) {
return {
node: server.hostname,
threadId,
version: entry.version,
nodeId: entry.nodeId,
record: await describeRecord(entry.value),
};
}
}
return { node: server.hostname, threadId, record: null };
}
}

export class PairWorker extends Resource {
static loadAsInstance = false;

get(target) {
target.checkPermission = false;
return { threadId };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type PairRecord @table @export {
id: String @primaryKey
token: String
sourceNode: String
sourceThread: Long
payload: Blob
}
Loading
Loading