MCPcopy Create free account
hub / github.com/apache/maka / create

Method create

packages/storage/src/task-ledger-store.ts:188–259  ·  view source on GitHub ↗
(
    sessionId: string,
    drafts: unknown,
    context: TaskLedgerMutationContext = {},
  )

Source from the content-addressed store, hash-verified

186 }
187
188 async create(
189 sessionId: string,
190 drafts: unknown,
191 context: TaskLedgerMutationContext = {},
192 ): Promise<{ created: Task[]; total: number }> {
193 assertSafeSessionId(sessionId);
194 if (!Array.isArray(drafts) || drafts.length === 0) {
195 throw new Error('Task creation requires at least one task draft');
196 }
197 // Front-door the per-batch cap before generating ids or normalizing drafts:
198 // a single call can never add more than the absolute ledger cap, and rejecting
199 // here avoids generating N uuids for a batch the write-queue total check
200 // would refuse anyway. The total (existing + new) cap is still enforced
201 // inside the serialized mutate callback below.
202 if (drafts.length > TASK_LEDGER_MAX_TASKS) {
203 throw new Error(
204 `Task creation batch of ${drafts.length} tasks exceeds the ${TASK_LEDGER_MAX_TASKS}-task per-batch cap; split the work into smaller calls.`,
205 );
206 }
207 const normalizedDrafts = drafts.map((draft) => {
208 const normalized = normalizeCreateTaskInput(draft);
209 if (!normalized.ok) throw new Error(normalized.message);
210 return normalized.value;
211 });
212 const created: Task[] = [];
213 // Cap check runs inside the serialized mutate callback (after reading the
214 // current ledger) so concurrent creates cannot race past the limit, and a
215 // rejected create never touches the file.
216 const all = await this.mutate(
217 sessionId,
218 (tasks) => {
219 if (tasks.length + normalizedDrafts.length > TASK_LEDGER_MAX_TASKS) {
220 throw new Error(
221 `Task ledger is limited to ${TASK_LEDGER_MAX_TASKS} tasks total per session ` +
222 `(currently ${tasks.length}, adding ${normalizedDrafts.length}). This is a hard runaway guard on the ` +
223 'total count — completed or cancelled tasks still count, so batch related work into fewer, ' +
224 'coarser tasks instead.',
225 );
226 }
227 const now = Date.now();
228 for (const draft of normalizedDrafts) {
229 const parent = draft.parentId ? findTaskByRef(tasks, draft.parentId) : undefined;
230 if (draft.parentId && !parent) throw new Error(`No such parent task: ${draft.parentId}`);
231 if (parent && isTerminalTaskStatus(parent.status)) {
232 throw new Error(`Cannot create a child under terminal task ${parent.key}`);
233 }
234 const task: Task = {
235 id: randomUUID(),
236 key: nextTaskKey([...tasks, ...created], parent),
237 subject: draft.subject,
238 status: 'pending',
239 createdAt: now,
240 updatedAt: now,
241 ...(parent ? { parentId: parent.id } : {}),
242 ...(ownerFromContext(context) ? { owner: ownerFromContext(context) } : {}),
243 };
244 created.push(task);
245 }

Callers

nothing calls this directly

Calls 11

mutateMethod · 0.95
normalizeCreateTaskInputFunction · 0.90
findTaskByRefFunction · 0.90
isTerminalTaskStatusFunction · 0.90
nextTaskKeyFunction · 0.85
ownerFromContextFunction · 0.85
buildTaskLedgerEventFunction · 0.85
assertSafeSessionIdFunction · 0.70
nowMethod · 0.65
pushMethod · 0.65

Tested by

no test coverage detected