@kanf/wema-kake 0.1.2 → 0.1.4

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.
@@ -0,0 +1,51 @@
1
+ import { isValidSlug } from '../shared/slug';
2
+ import { parseId, parseNoteIds, parsePositions, RejectError } from './validate';
3
+ /**
4
+ * 元のページから付箋を消す操作の clientId。送った画面の clientId を使うと、その画面は、自分の操作の
5
+ * 確定と見なして(覚えのない opId なので無視して)、消したことを手元に反映しない
6
+ */
7
+ const REMOVE_CLIENT_ID = 'transfer';
8
+ export async function transferNotes(env, input) {
9
+ const { actor, clientId, opId, from, to, copy, summary } = input;
10
+ let noteIds;
11
+ let positions;
12
+ try {
13
+ if (!isValidSlug(from) || !isValidSlug(to))
14
+ throw new RejectError('invalid page');
15
+ // 消す操作は別の clientId で記録するので、ここで確かめておく(送り先は、置く前に確かめる)
16
+ parseId(opId, 'opId');
17
+ noteIds = parseNoteIds(input.noteIds);
18
+ positions = parsePositions(input.positions);
19
+ }
20
+ catch (e) {
21
+ if (e instanceof RejectError)
22
+ return { ok: false, code: 'invalid', reason: e.message };
23
+ throw e;
24
+ }
25
+ const taken = await env.PAGE.getByName(to).takeNotes({
26
+ actor, clientId, opId, from, noteIds, positions, keepAuthors: !copy, summary,
27
+ });
28
+ if (!taken.ok)
29
+ return { ok: false, code: taken.notFound ? 'not-found' : 'invalid', reason: taken.reason };
30
+ if (copy)
31
+ return { ok: true, noteIds: taken.noteIds, received: taken.seq, removed: null };
32
+ const removed = await env.PAGE.getByName(from)
33
+ .removeNotes({ actor, clientId: REMOVE_CLIENT_ID, opId, noteIds, versions: taken.versions, to, summary })
34
+ .catch((e) => ({ ok: false, reason: e instanceof Error ? e.message : String(e) }));
35
+ if (!removed.ok) {
36
+ return {
37
+ ok: false,
38
+ code: 'partial',
39
+ reason: `placed the notes in ${to} (operation ${taken.seq}), but could not remove them from ${from}: ${removed.reason}`,
40
+ };
41
+ }
42
+ if (removed.kept.length > 0) {
43
+ return {
44
+ ok: false,
45
+ code: 'partial',
46
+ reason: `placed the notes in ${to} (operation ${taken.seq}), but left ${removed.kept.join(', ')} in ${from}` +
47
+ ` because they were changed or removed there while moving (the copies in ${to} are from before the change)`,
48
+ };
49
+ }
50
+ return { ok: true, noteIds: taken.noteIds, received: taken.seq, removed: removed.seq };
51
+ }
@@ -17,5 +17,12 @@ declare function id(v: unknown, what: string): string;
17
17
  export { id as parseId };
18
18
  /** 付箋の、id と zIndex 以外のフィールド */
19
19
  export type NoteField = Exclude<keyof WemaNote, 'id' | 'zIndex'>;
20
+ /** 他のページへ移す(写す)付箋の id の一覧。重複は 1 つにする */
21
+ export declare function parseNoteIds(input: unknown): string[];
22
+ /** 付箋の id から、位置(`{ x, y }`)。省略されていれば空 */
23
+ export declare function parsePositions(input: unknown): Map<string, {
24
+ x: number;
25
+ y: number;
26
+ }>;
20
27
  /** 外から来たデルタの形を検証し、既知のフィールドだけを持つデルタにして返す */
21
28
  export declare function parseDeltas(input: unknown): HistoryDelta[];
@@ -193,6 +193,23 @@ function parseDelta(v) {
193
193
  throw new RejectError('unknown delta type');
194
194
  }
195
195
  }
196
+ /** 他のページへ移す(写す)付箋の id の一覧。重複は 1 つにする */
197
+ export function parseNoteIds(input) {
198
+ if (!Array.isArray(input) || input.length === 0)
199
+ throw new RejectError('invalid noteIds');
200
+ if (input.length > MAX_DELTAS)
201
+ throw new RejectError(`too many notes (${input.length}, limit ${MAX_DELTAS})`);
202
+ return [...new Set(input.map((v) => id(v, 'note id')))];
203
+ }
204
+ /** 付箋の id から、位置(`{ x, y }`)。省略されていれば空 */
205
+ export function parsePositions(input) {
206
+ if (input === undefined || input === null)
207
+ return new Map();
208
+ return new Map(Object.entries(obj(input, 'positions')).map(([key, v]) => {
209
+ const p = obj(v, 'position');
210
+ return [id(key, 'note id'), { x: num(p.x, 'x'), y: num(p.y, 'y') }];
211
+ }));
212
+ }
196
213
  /** 外から来たデルタの形を検証し、既知のフィールドだけを持つデルタにして返す */
197
214
  export function parseDeltas(input) {
198
215
  if (!Array.isArray(input) || input.length === 0)