@myagentroam/agent 0.9.157 → 0.9.158
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-core/session/catalog.d.ts +3 -0
- package/dist/agent-core/session/catalog.js +1 -0
- package/dist/agent-core/session/jsonl-store.d.ts +6 -2
- package/dist/agent-core/session/jsonl-store.js +180 -8
- package/dist/agent-core/tools/code-mode/quickjs-engine.js +12 -0
- package/package.json +1 -1
|
@@ -4,6 +4,8 @@ import type { SessionListInput, SessionSource } from './types.js';
|
|
|
4
4
|
export interface MarAgentSessionSummary {
|
|
5
5
|
id: string;
|
|
6
6
|
title: string;
|
|
7
|
+
/** First non-empty user input, whitespace-normalized and bounded to 160 characters. */
|
|
8
|
+
firstUserMessagePreview?: string;
|
|
7
9
|
workspace: string;
|
|
8
10
|
createdAt: string;
|
|
9
11
|
lastActivityAt: string;
|
|
@@ -54,6 +56,7 @@ export interface MarAgentSessionImage {
|
|
|
54
56
|
/** Public session catalog facade. Storage details remain SDK-private. */
|
|
55
57
|
export interface MarAgentSessionCatalog {
|
|
56
58
|
list(input?: SessionListInput): Promise<MarAgentSessionPage>;
|
|
59
|
+
firstUserMessagePreview(sessionId: string): Promise<string | undefined>;
|
|
57
60
|
executionConfiguration(sessionId: string): Promise<{
|
|
58
61
|
readonly modelId: string;
|
|
59
62
|
readonly modelName?: string;
|
|
@@ -7,6 +7,7 @@ export async function openMarAgentSessionCatalog(input) {
|
|
|
7
7
|
const store = await JsonlSessionStore.open(input.homeDirectory);
|
|
8
8
|
return {
|
|
9
9
|
list: (options) => store.list(options),
|
|
10
|
+
firstUserMessagePreview: (sessionId) => store.firstUserMessagePreview(sessionId),
|
|
10
11
|
executionConfiguration: (sessionId) => store.executionConfiguration(sessionId),
|
|
11
12
|
history: async (sessionId, options = {}) => {
|
|
12
13
|
const beforeSequence = parseCursor(options.cursor);
|
|
@@ -64,6 +64,8 @@ interface SessionMeta {
|
|
|
64
64
|
todoSequence?: number;
|
|
65
65
|
todoRevision: number;
|
|
66
66
|
executionModelIndexed?: true;
|
|
67
|
+
firstUserMessageIndexed?: true;
|
|
68
|
+
firstUserMessagePreview?: string;
|
|
67
69
|
modelId?: string;
|
|
68
70
|
modelName?: string;
|
|
69
71
|
reasoningEffort?: string;
|
|
@@ -184,12 +186,13 @@ export declare class JsonlSessionStore {
|
|
|
184
186
|
reasoningEffort?: string;
|
|
185
187
|
modelName?: string;
|
|
186
188
|
modelId?: string;
|
|
187
|
-
id: string;
|
|
188
|
-
title: string;
|
|
189
189
|
workspace: string;
|
|
190
190
|
createdAt: string;
|
|
191
191
|
lastActivityAt: string;
|
|
192
192
|
source: SessionSource;
|
|
193
|
+
firstUserMessagePreview?: string;
|
|
194
|
+
id: string;
|
|
195
|
+
title: string;
|
|
193
196
|
}[];
|
|
194
197
|
}>;
|
|
195
198
|
listSubagentChildren(parentSessionId: string): Promise<{
|
|
@@ -216,6 +219,7 @@ export declare class JsonlSessionStore {
|
|
|
216
219
|
readonly reasoningEffort?: string;
|
|
217
220
|
} | undefined>;
|
|
218
221
|
sessionTree(sessionId: string): Promise<readonly string[]>;
|
|
222
|
+
firstUserMessagePreview(sessionId: string): Promise<string | undefined>;
|
|
219
223
|
delete(sessionId: string): Promise<{
|
|
220
224
|
readonly deleted: boolean;
|
|
221
225
|
}>;
|
|
@@ -158,6 +158,7 @@ export class JsonlSessionStore {
|
|
|
158
158
|
closed: false,
|
|
159
159
|
indexDirty: false,
|
|
160
160
|
dirtySessionVersions: new Map(),
|
|
161
|
+
previewOnlyDirtySessions: new Set(),
|
|
161
162
|
pendingPublishIds: new Set(),
|
|
162
163
|
codeStateWrites: new Map(),
|
|
163
164
|
recordWrites: new Map(),
|
|
@@ -176,19 +177,26 @@ export class JsonlSessionStore {
|
|
|
176
177
|
if (!disk)
|
|
177
178
|
throw new MarAgentError('MAR_AGENT_SESSION_CORRUPT', 'Session index is missing.');
|
|
178
179
|
const dirty = new Map(this.#shared.dirtySessionVersions);
|
|
180
|
+
const previewOnly = new Set(this.#shared.previewOnlyDirtySessions);
|
|
179
181
|
const sessions = new Map(disk.sessions.map((session) => [session.id, session]));
|
|
180
182
|
const created = new Set(createdIds);
|
|
181
183
|
for (const session of this.#shared.index.sessions) {
|
|
182
184
|
const current = sessions.get(session.id);
|
|
183
185
|
// Disk membership is authoritative: a stale in-memory snapshot cannot revive a deletion.
|
|
184
186
|
if (created.has(session.id) || (current && dirty.has(session.id)))
|
|
185
|
-
sessions.set(session.id,
|
|
187
|
+
sessions.set(session.id, current && previewOnly.has(session.id)
|
|
188
|
+
? mergeFirstUserMessagePreviewCache(current, session)
|
|
189
|
+
: structuredClone(session));
|
|
186
190
|
}
|
|
187
191
|
for (const deletedId of typeof deletedIds === 'string' ? [deletedIds] : (deletedIds ?? []))
|
|
188
192
|
sessions.delete(deletedId);
|
|
189
193
|
const updated = {
|
|
190
194
|
version: 1,
|
|
191
|
-
revision:
|
|
195
|
+
revision: createdIds.length > 0 ||
|
|
196
|
+
deletedIds !== undefined ||
|
|
197
|
+
[...dirty.keys()].some((id) => !previewOnly.has(id))
|
|
198
|
+
? Math.max(disk.revision, this.#shared.index.revision) + 1
|
|
199
|
+
: disk.revision,
|
|
192
200
|
sessions: [...sessions.values()]
|
|
193
201
|
};
|
|
194
202
|
await persistSessionIndex(path, updated);
|
|
@@ -196,8 +204,10 @@ export class JsonlSessionStore {
|
|
|
196
204
|
// A different creation still needs its own index transaction to publish its directory.
|
|
197
205
|
if (this.#shared.pendingPublishIds.has(id) && !created.has(id))
|
|
198
206
|
continue;
|
|
199
|
-
if (this.#shared.dirtySessionVersions.get(id) === version)
|
|
207
|
+
if (this.#shared.dirtySessionVersions.get(id) === version) {
|
|
200
208
|
this.#shared.dirtySessionVersions.delete(id);
|
|
209
|
+
this.#shared.previewOnlyDirtySessions.delete(id);
|
|
210
|
+
}
|
|
201
211
|
}
|
|
202
212
|
for (const id of created)
|
|
203
213
|
this.#shared.pendingPublishIds.delete(id);
|
|
@@ -234,7 +244,11 @@ export class JsonlSessionStore {
|
|
|
234
244
|
sessions: disk.sessions
|
|
235
245
|
.map((session) => {
|
|
236
246
|
const current = local.get(session.id);
|
|
237
|
-
|
|
247
|
+
if (!current || !this.#shared.dirtySessionVersions.has(session.id))
|
|
248
|
+
return session;
|
|
249
|
+
return this.#shared.previewOnlyDirtySessions.has(session.id)
|
|
250
|
+
? mergeFirstUserMessagePreviewCache(session, current)
|
|
251
|
+
: current;
|
|
238
252
|
})
|
|
239
253
|
.concat(this.#shared.index.sessions.filter((session) => this.#shared.pendingPublishIds.has(session.id) && !published.has(session.id)))
|
|
240
254
|
};
|
|
@@ -272,7 +286,12 @@ export class JsonlSessionStore {
|
|
|
272
286
|
source: normalizeSessionSource(input.source),
|
|
273
287
|
nextSequence: 1,
|
|
274
288
|
automaticTitlePending: input.title === undefined,
|
|
275
|
-
resume: {
|
|
289
|
+
resume: {
|
|
290
|
+
version: 1,
|
|
291
|
+
todoRevision: 0,
|
|
292
|
+
executionModelIndexed: true,
|
|
293
|
+
firstUserMessageIndexed: true
|
|
294
|
+
},
|
|
276
295
|
segments: []
|
|
277
296
|
};
|
|
278
297
|
const publication = await this.#beginUnpublishedSession(id);
|
|
@@ -520,7 +539,12 @@ export class JsonlSessionStore {
|
|
|
520
539
|
source: { type: 'user' },
|
|
521
540
|
nextSequence: 1,
|
|
522
541
|
automaticTitlePending: false,
|
|
523
|
-
resume: {
|
|
542
|
+
resume: {
|
|
543
|
+
version: 1,
|
|
544
|
+
todoRevision: 0,
|
|
545
|
+
executionModelIndexed: true,
|
|
546
|
+
firstUserMessageIndexed: true
|
|
547
|
+
},
|
|
524
548
|
segments: []
|
|
525
549
|
};
|
|
526
550
|
const publication = await this.#beginUnpublishedSession(target.id);
|
|
@@ -852,7 +876,7 @@ export class JsonlSessionStore {
|
|
|
852
876
|
meta.lastActivityAt = clearedAt;
|
|
853
877
|
meta.nextSequence = 2;
|
|
854
878
|
meta.storageTransactionId = transactionId;
|
|
855
|
-
meta.resume = { version: 1, todoRevision: 0 };
|
|
879
|
+
meta.resume = { version: 1, todoRevision: 0, firstUserMessageIndexed: true };
|
|
856
880
|
meta.segments = staged.segments;
|
|
857
881
|
this.#shared.segments.set(sessionId, 1);
|
|
858
882
|
this.#shared.index.revision++;
|
|
@@ -1316,6 +1340,9 @@ export class JsonlSessionStore {
|
|
|
1316
1340
|
const sessions = ordered.slice(start, start + limit).map((session) => ({
|
|
1317
1341
|
id: session.id,
|
|
1318
1342
|
title: session.title,
|
|
1343
|
+
...(session.resume?.firstUserMessagePreview === undefined
|
|
1344
|
+
? {}
|
|
1345
|
+
: { firstUserMessagePreview: session.resume.firstUserMessagePreview }),
|
|
1319
1346
|
workspace: session.workspace,
|
|
1320
1347
|
createdAt: session.createdAt,
|
|
1321
1348
|
lastActivityAt: session.lastActivityAt,
|
|
@@ -1403,6 +1430,11 @@ export class JsonlSessionStore {
|
|
|
1403
1430
|
const resume = meta.resume;
|
|
1404
1431
|
if (resume?.version !== 1 || !Number.isSafeInteger(resume.todoRevision))
|
|
1405
1432
|
return;
|
|
1433
|
+
if (resume.firstUserMessageIndexed === true && resume.firstUserMessagePreview === undefined) {
|
|
1434
|
+
const preview = userMessagePreviewFromRecord(record);
|
|
1435
|
+
if (preview !== undefined)
|
|
1436
|
+
resume.firstUserMessagePreview = preview;
|
|
1437
|
+
}
|
|
1406
1438
|
const executionModel = executionModelFromRecord(record);
|
|
1407
1439
|
if (executionModel !== undefined) {
|
|
1408
1440
|
resume.executionModelIndexed = true;
|
|
@@ -1488,6 +1520,56 @@ export class JsonlSessionStore {
|
|
|
1488
1520
|
contextRecords: state.contextRecords
|
|
1489
1521
|
};
|
|
1490
1522
|
}
|
|
1523
|
+
async firstUserMessagePreview(sessionId) {
|
|
1524
|
+
this.#assertOpen();
|
|
1525
|
+
await this.#refreshIndex();
|
|
1526
|
+
await this.#ensureFirstUserMessageIndexed(sessionId);
|
|
1527
|
+
return this.#shared.index.sessions.find((session) => session.id === sessionId)?.resume
|
|
1528
|
+
?.firstUserMessagePreview;
|
|
1529
|
+
}
|
|
1530
|
+
async #ensureFirstUserMessageIndexed(sessionId) {
|
|
1531
|
+
for (;;) {
|
|
1532
|
+
const before = this.#shared.index.sessions.find((session) => session.id === sessionId);
|
|
1533
|
+
if (before === undefined)
|
|
1534
|
+
throw new MarAgentError('MAR_AGENT_SESSION_NOT_FOUND', 'Session was not found.');
|
|
1535
|
+
if (before.resume?.firstUserMessageIndexed === true)
|
|
1536
|
+
return;
|
|
1537
|
+
const nextSequence = before.nextSequence;
|
|
1538
|
+
const transactionId = before.storageTransactionId;
|
|
1539
|
+
let preview;
|
|
1540
|
+
try {
|
|
1541
|
+
for (const path of await this.#segmentPaths(sessionId)) {
|
|
1542
|
+
for await (const record of readRecordsFromHead(path)) {
|
|
1543
|
+
preview = userMessagePreviewFromRecord(record);
|
|
1544
|
+
if (preview !== undefined)
|
|
1545
|
+
break;
|
|
1546
|
+
}
|
|
1547
|
+
if (preview !== undefined)
|
|
1548
|
+
break;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
catch (error) {
|
|
1552
|
+
if (error.code !== 'ENOENT' &&
|
|
1553
|
+
!(error instanceof MarAgentError && error.code === 'MAR_AGENT_SESSION_NOT_FOUND'))
|
|
1554
|
+
throw error;
|
|
1555
|
+
}
|
|
1556
|
+
await this.#refreshIndex();
|
|
1557
|
+
const current = this.#shared.index.sessions.find((session) => session.id === sessionId);
|
|
1558
|
+
if (current === undefined)
|
|
1559
|
+
throw new MarAgentError('MAR_AGENT_SESSION_NOT_FOUND', 'Session was not found.');
|
|
1560
|
+
if (current.resume?.firstUserMessageIndexed === true)
|
|
1561
|
+
return;
|
|
1562
|
+
if (current.nextSequence !== nextSequence || current.storageTransactionId !== transactionId)
|
|
1563
|
+
continue;
|
|
1564
|
+
const resume = (current.resume ??= { version: 1, todoRevision: 0 });
|
|
1565
|
+
resume.firstUserMessageIndexed = true;
|
|
1566
|
+
if (preview !== undefined)
|
|
1567
|
+
resume.firstUserMessagePreview = preview;
|
|
1568
|
+
// Derived preview caches do not change list membership, ordering or filters.
|
|
1569
|
+
this.#markIndexDirty(sessionId, true);
|
|
1570
|
+
return;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1491
1573
|
async #ensureExecutionModelIndexed(sessionId) {
|
|
1492
1574
|
const pending = this.#shared.executionModelReads.get(sessionId);
|
|
1493
1575
|
if (pending !== undefined)
|
|
@@ -1586,7 +1668,11 @@ export class JsonlSessionStore {
|
|
|
1586
1668
|
if (this.#leaseClosed || this.#shared.closed)
|
|
1587
1669
|
throw new MarAgentError('MAR_AGENT_DISPOSED', 'Session store is closed.');
|
|
1588
1670
|
}
|
|
1589
|
-
#markIndexDirty(sessionId) {
|
|
1671
|
+
#markIndexDirty(sessionId, previewOnly = false) {
|
|
1672
|
+
if (!previewOnly)
|
|
1673
|
+
this.#shared.previewOnlyDirtySessions.delete(sessionId);
|
|
1674
|
+
else if (!this.#shared.dirtySessionVersions.has(sessionId))
|
|
1675
|
+
this.#shared.previewOnlyDirtySessions.add(sessionId);
|
|
1590
1676
|
this.#shared.indexDirty = true;
|
|
1591
1677
|
this.#shared.dirtySessionVersions.set(sessionId, (this.#shared.dirtySessionVersions.get(sessionId) ?? 0) + 1);
|
|
1592
1678
|
}
|
|
@@ -1679,6 +1765,26 @@ export class JsonlSessionStore {
|
|
|
1679
1765
|
JsonlSessionStore.#instances.delete(this.#shared.root);
|
|
1680
1766
|
}
|
|
1681
1767
|
}
|
|
1768
|
+
/** Merge a derived cache only onto the unchanged history it was computed from. */
|
|
1769
|
+
function mergeFirstUserMessagePreviewCache(current, cached) {
|
|
1770
|
+
if (cached.resume?.firstUserMessageIndexed !== true ||
|
|
1771
|
+
current.nextSequence !== cached.nextSequence ||
|
|
1772
|
+
current.storageTransactionId !== cached.storageTransactionId ||
|
|
1773
|
+
current.resume?.firstUserMessagePreview !== undefined ||
|
|
1774
|
+
(current.resume?.firstUserMessageIndexed === true &&
|
|
1775
|
+
cached.resume.firstUserMessagePreview === undefined))
|
|
1776
|
+
return current;
|
|
1777
|
+
return {
|
|
1778
|
+
...current,
|
|
1779
|
+
resume: {
|
|
1780
|
+
...(current.resume ?? { version: 1, todoRevision: 0 }),
|
|
1781
|
+
firstUserMessageIndexed: true,
|
|
1782
|
+
...(cached.resume?.firstUserMessagePreview === undefined
|
|
1783
|
+
? {}
|
|
1784
|
+
: { firstUserMessagePreview: cached.resume.firstUserMessagePreview })
|
|
1785
|
+
}
|
|
1786
|
+
};
|
|
1787
|
+
}
|
|
1682
1788
|
async function readSessionIndex(path) {
|
|
1683
1789
|
let raw;
|
|
1684
1790
|
try {
|
|
@@ -2157,7 +2263,9 @@ function deriveExecutionState(records) {
|
|
|
2157
2263
|
let todoRevision = 0;
|
|
2158
2264
|
let todoItems = [];
|
|
2159
2265
|
let executionModel;
|
|
2266
|
+
let firstUserMessagePreview;
|
|
2160
2267
|
for (const record of records) {
|
|
2268
|
+
firstUserMessagePreview ??= userMessagePreviewFromRecord(record);
|
|
2161
2269
|
if (record.type === 'session.created')
|
|
2162
2270
|
automaticTitle =
|
|
2163
2271
|
record.payload?.automaticTitle === true;
|
|
@@ -2198,10 +2306,21 @@ function deriveExecutionState(records) {
|
|
|
2198
2306
|
...(todoSequence === undefined ? {} : { todoSequence }),
|
|
2199
2307
|
todoRevision,
|
|
2200
2308
|
executionModelIndexed: true,
|
|
2309
|
+
firstUserMessageIndexed: true,
|
|
2310
|
+
...(firstUserMessagePreview === undefined ? {} : { firstUserMessagePreview }),
|
|
2201
2311
|
...(executionModel === undefined ? {} : executionModel)
|
|
2202
2312
|
}
|
|
2203
2313
|
};
|
|
2204
2314
|
}
|
|
2315
|
+
function userMessagePreviewFromRecord(record) {
|
|
2316
|
+
if (record.type !== 'turn.user' ||
|
|
2317
|
+
!isObject(record.payload) ||
|
|
2318
|
+
record.payload.inputSource === 'parent_agent' ||
|
|
2319
|
+
typeof record.payload.prompt !== 'string')
|
|
2320
|
+
return undefined;
|
|
2321
|
+
const preview = record.payload.prompt.trim().replace(/\s+/gu, ' ').slice(0, 160);
|
|
2322
|
+
return preview || undefined;
|
|
2323
|
+
}
|
|
2205
2324
|
function executionModelFromRecord(record) {
|
|
2206
2325
|
if (record.type !== 'execution.header' || !isObject(record.payload))
|
|
2207
2326
|
return undefined;
|
|
@@ -2254,10 +2373,63 @@ function sameResumeIndex(left, right) {
|
|
|
2254
2373
|
left.todoSequence === right.todoSequence &&
|
|
2255
2374
|
left.todoRevision === right.todoRevision &&
|
|
2256
2375
|
left.executionModelIndexed === right.executionModelIndexed &&
|
|
2376
|
+
left.firstUserMessageIndexed === right.firstUserMessageIndexed &&
|
|
2377
|
+
left.firstUserMessagePreview === right.firstUserMessagePreview &&
|
|
2257
2378
|
left.modelId === right.modelId &&
|
|
2258
2379
|
left.modelName === right.modelName &&
|
|
2259
2380
|
left.reasoningEffort === right.reasoningEffort);
|
|
2260
2381
|
}
|
|
2382
|
+
/** Read only the prefix needed by discovery; never load the entire transcript. */
|
|
2383
|
+
async function* readRecordsFromHead(path) {
|
|
2384
|
+
const handle = await open(path, 'r');
|
|
2385
|
+
try {
|
|
2386
|
+
const { size } = await handle.stat();
|
|
2387
|
+
const chunk = Buffer.allocUnsafe(REVERSE_READ_CHUNK_BYTES);
|
|
2388
|
+
let position = 0;
|
|
2389
|
+
let pending = Buffer.alloc(0);
|
|
2390
|
+
while (position < size) {
|
|
2391
|
+
const { bytesRead } = await handle.read(chunk, 0, Math.min(chunk.length, size - position), position);
|
|
2392
|
+
if (bytesRead === 0)
|
|
2393
|
+
break;
|
|
2394
|
+
position += bytesRead;
|
|
2395
|
+
const data = Buffer.concat([pending, chunk.subarray(0, bytesRead)]);
|
|
2396
|
+
let start = 0;
|
|
2397
|
+
for (;;) {
|
|
2398
|
+
const end = data.indexOf(0x0a, start);
|
|
2399
|
+
if (end < 0)
|
|
2400
|
+
break;
|
|
2401
|
+
const line = data.subarray(start, end).toString('utf8');
|
|
2402
|
+
start = end + 1;
|
|
2403
|
+
if (!line)
|
|
2404
|
+
continue;
|
|
2405
|
+
let record;
|
|
2406
|
+
try {
|
|
2407
|
+
record = JSON.parse(line);
|
|
2408
|
+
}
|
|
2409
|
+
catch (cause) {
|
|
2410
|
+
throw new MarAgentError('MAR_AGENT_SESSION_CORRUPT', 'Session history is corrupt.', {
|
|
2411
|
+
cause
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
2414
|
+
yield record;
|
|
2415
|
+
}
|
|
2416
|
+
pending = Buffer.from(data.subarray(start));
|
|
2417
|
+
}
|
|
2418
|
+
if (pending.length > 0) {
|
|
2419
|
+
let record;
|
|
2420
|
+
try {
|
|
2421
|
+
record = JSON.parse(pending.toString('utf8'));
|
|
2422
|
+
}
|
|
2423
|
+
catch {
|
|
2424
|
+
return; // Readers ignore only an interrupted final line.
|
|
2425
|
+
}
|
|
2426
|
+
yield record;
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
finally {
|
|
2430
|
+
await handle.close();
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2261
2433
|
async function readRecords(path) {
|
|
2262
2434
|
const value = await readFile(path, 'utf8');
|
|
2263
2435
|
const lines = value.split('\n');
|
|
@@ -13,6 +13,18 @@ export async function createCodeModeEngine(options) {
|
|
|
13
13
|
if (disposed || runtime)
|
|
14
14
|
throw diagnostic('MAR_AGENT_CODE_FAILED', 'Engine is not reusable.');
|
|
15
15
|
runtime = quickjs.newRuntime();
|
|
16
|
+
// QuickJS 0.32.0 caches the job's context-pointer view across WASM memory growth
|
|
17
|
+
// (upstream #240). A detached view creates an unowned Context and breaks disposal.
|
|
18
|
+
// Keep this dependency-specific correction inside the worker engine; preserve its
|
|
19
|
+
// pointer allocation/free lifecycle and always read from the current heap.
|
|
20
|
+
const newMutablePointerArray = runtime.memory.newMutablePointerArray.bind(runtime.memory);
|
|
21
|
+
runtime.memory.newMutablePointerArray = (length) => {
|
|
22
|
+
const pointer = newMutablePointerArray(length);
|
|
23
|
+
Object.defineProperty(pointer.value, 'typedArray', {
|
|
24
|
+
get: () => new Int32Array(runtime.module.HEAP8.buffer, pointer.value.ptr, length)
|
|
25
|
+
});
|
|
26
|
+
return pointer;
|
|
27
|
+
};
|
|
16
28
|
runtime.setMemoryLimit(input.limits.memoryBytes);
|
|
17
29
|
runtime.setMaxStackSize(input.limits.stackBytes);
|
|
18
30
|
let executionMs = 0;
|