@mahmulp/feedback-sdk 0.0.1 → 0.1.0

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/mock.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mock.ts"],"names":[],"mappings":"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","file":"mock.cjs","sourcesContent":["import type {\n CreateFeedbackInput,\n Feedback,\n FeedbackAuthor,\n FeedbackCoordinates,\n FeedbackStatus,\n FeedbackTransport,\n ListFeedbackQuery,\n ListFeedbackResult,\n} from \"./types.js\";\n\n/**\n * In-memory transport for local development / demos / tests.\n *\n * import { createMockTransport } from '@mahmulp/feedback-sdk/mock'\n *\n * No persistence, no network. Useful before the API is wired up.\n */\n\nexport interface MockTransportOptions {\n /** Optional initial feedback records (e.g. seeded from a fixture). */\n initial?: Feedback[];\n /** Override id generation (defaults to `fb_<timestamp>_<rand>`). */\n generateId?: () => string;\n /** Optional fake latency in ms, applied to every call. */\n latencyMs?: number;\n}\n\nexport function createMockTransport(options: MockTransportOptions = {}): FeedbackTransport & {\n /** Direct read of the in-memory store for tests / debugging. */\n _all(): Feedback[];\n _reset(): void;\n} {\n const items: Feedback[] = options.initial ? options.initial.map(clone) : [];\n const genId = options.generateId ?? defaultGenerateId;\n const latency = options.latencyMs ?? 0;\n\n async function delay() {\n if (latency > 0) await new Promise((r) => setTimeout(r, latency));\n }\n\n return {\n async list(query: ListFeedbackQuery): Promise<ListFeedbackResult> {\n await delay();\n // When `projectId` is empty, the SDK is relying on the API to scope by\n // key — return every record. When set, scope by it.\n const filtered = items\n .filter((f) => (query.projectId ? f.projectId === query.projectId : true))\n .filter((f) => (query.pageUrl ? f.pageUrl === query.pageUrl : true))\n .filter((f) => (query.status ? f.status === query.status : true))\n .map(clone);\n return { items: filtered };\n },\n\n async create(input: CreateFeedbackInput): Promise<Feedback> {\n await delay();\n const now = new Date().toISOString();\n const id = genId();\n const fb: Feedback = {\n id,\n projectId: input.projectId,\n pageUrl: input.pageUrl,\n selector: input.selector,\n coordinates: { ...input.coordinates },\n viewport: { ...input.viewport },\n status: \"open\",\n thread: input.comment\n ? [\n {\n id: `cm_${id}_0`,\n author: { ...input.comment.author },\n body: input.comment.body,\n createdAt: now,\n },\n ]\n : [],\n createdAt: now,\n updatedAt: now,\n };\n items.push(fb);\n return clone(fb);\n },\n\n async reply(\n feedbackId: string,\n comment: { author: FeedbackAuthor; body: string }\n ): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n const now = new Date().toISOString();\n fb.thread.push({\n id: `cm_${feedbackId}_${fb.thread.length}`,\n author: { ...comment.author },\n body: comment.body,\n createdAt: now,\n });\n fb.updatedAt = now;\n return clone(fb);\n },\n\n async setStatus(feedbackId: string, status: FeedbackStatus): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.status = status;\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n async move(feedbackId: string, coordinates: FeedbackCoordinates): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.coordinates = { ...coordinates };\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n async uploadScreenshot(feedbackId: string, _blob: Blob): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.screenshotKey = `screenshots/${feedbackId}.png`;\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n _all() {\n return items.map(clone);\n },\n _reset() {\n items.length = 0;\n },\n };\n}\n\nfunction defaultGenerateId(): string {\n return `fb_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction clone<T>(value: T): T {\n // Structured clone is fine here; the records are plain JSON shapes.\n return JSON.parse(JSON.stringify(value)) as T;\n}\n"]}
1
+ {"version":3,"sources":["../src/mock.ts"],"names":[],"mappings":"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","file":"mock.cjs","sourcesContent":["import type {\r\n CreateFeedbackInput,\r\n Feedback,\r\n FeedbackAuthor,\r\n FeedbackCoordinates,\r\n FeedbackStatus,\r\n FeedbackTransport,\r\n ListFeedbackQuery,\r\n ListFeedbackResult,\r\n} from \"./types.js\";\r\n\r\n/**\r\n * In-memory transport for local development / demos / tests.\r\n *\r\n * import { createMockTransport } from '@mahmulp/feedback-sdk/mock'\r\n *\r\n * No persistence, no network. Useful before the API is wired up.\r\n */\r\n\r\nexport interface MockTransportOptions {\r\n /** Optional initial feedback records (e.g. seeded from a fixture). */\r\n initial?: Feedback[];\r\n /** Override id generation (defaults to `fb_<timestamp>_<rand>`). */\r\n generateId?: () => string;\r\n /** Optional fake latency in ms, applied to every call. */\r\n latencyMs?: number;\r\n}\r\n\r\nexport function createMockTransport(options: MockTransportOptions = {}): FeedbackTransport & {\r\n /** Direct read of the in-memory store for tests / debugging. */\r\n _all(): Feedback[];\r\n _reset(): void;\r\n} {\r\n const items: Feedback[] = options.initial ? options.initial.map(clone) : [];\r\n const genId = options.generateId ?? defaultGenerateId;\r\n const latency = options.latencyMs ?? 0;\r\n\r\n async function delay() {\r\n if (latency > 0) await new Promise((r) => setTimeout(r, latency));\r\n }\r\n\r\n return {\r\n async list(query: ListFeedbackQuery): Promise<ListFeedbackResult> {\r\n await delay();\r\n // When `projectId` is empty, the SDK is relying on the API to scope by\r\n // key — return every record. When set, scope by it.\r\n const filtered = items\r\n .filter((f) => (query.projectId ? f.projectId === query.projectId : true))\r\n .filter((f) => (query.pageUrl ? f.pageUrl === query.pageUrl : true))\r\n .filter((f) => (query.status ? f.status === query.status : true))\r\n .map(clone);\r\n return { items: filtered };\r\n },\r\n\r\n async create(input: CreateFeedbackInput): Promise<Feedback> {\r\n await delay();\r\n const now = new Date().toISOString();\r\n const id = genId();\r\n const fb: Feedback = {\r\n id,\r\n projectId: input.projectId,\r\n pageUrl: input.pageUrl,\r\n selector: input.selector,\r\n coordinates: { ...input.coordinates },\r\n viewport: { ...input.viewport },\r\n status: \"open\",\r\n thread: input.comment\r\n ? [\r\n {\r\n id: `cm_${id}_0`,\r\n author: { ...input.comment.author },\r\n body: input.comment.body,\r\n createdAt: now,\r\n },\r\n ]\r\n : [],\r\n createdAt: now,\r\n updatedAt: now,\r\n };\r\n items.push(fb);\r\n return clone(fb);\r\n },\r\n\r\n async reply(\r\n feedbackId: string,\r\n comment: { author: FeedbackAuthor; body: string }\r\n ): Promise<Feedback> {\r\n await delay();\r\n const fb = items.find((f) => f.id === feedbackId);\r\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\r\n const now = new Date().toISOString();\r\n fb.thread.push({\r\n id: `cm_${feedbackId}_${fb.thread.length}`,\r\n author: { ...comment.author },\r\n body: comment.body,\r\n createdAt: now,\r\n });\r\n fb.updatedAt = now;\r\n return clone(fb);\r\n },\r\n\r\n async setStatus(feedbackId: string, status: FeedbackStatus): Promise<Feedback> {\r\n await delay();\r\n const fb = items.find((f) => f.id === feedbackId);\r\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\r\n fb.status = status;\r\n fb.updatedAt = new Date().toISOString();\r\n return clone(fb);\r\n },\r\n\r\n async move(feedbackId: string, coordinates: FeedbackCoordinates): Promise<Feedback> {\r\n await delay();\r\n const fb = items.find((f) => f.id === feedbackId);\r\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\r\n fb.coordinates = { ...coordinates };\r\n fb.updatedAt = new Date().toISOString();\r\n return clone(fb);\r\n },\r\n\r\n async uploadScreenshot(feedbackId: string, _blob: Blob): Promise<Feedback> {\r\n await delay();\r\n const fb = items.find((f) => f.id === feedbackId);\r\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\r\n fb.screenshotKey = `screenshots/${feedbackId}.png`;\r\n fb.updatedAt = new Date().toISOString();\r\n return clone(fb);\r\n },\r\n\r\n _all() {\r\n return items.map(clone);\r\n },\r\n _reset() {\r\n items.length = 0;\r\n },\r\n };\r\n}\r\n\r\nfunction defaultGenerateId(): string {\r\n return `fb_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\r\n}\r\n\r\nfunction clone<T>(value: T): T {\r\n // Structured clone is fine here; the records are plain JSON shapes.\r\n return JSON.parse(JSON.stringify(value)) as T;\r\n}\r\n"]}
package/dist/mock.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mock.ts"],"names":[],"mappings":"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","file":"mock.js","sourcesContent":["import type {\n CreateFeedbackInput,\n Feedback,\n FeedbackAuthor,\n FeedbackCoordinates,\n FeedbackStatus,\n FeedbackTransport,\n ListFeedbackQuery,\n ListFeedbackResult,\n} from \"./types.js\";\n\n/**\n * In-memory transport for local development / demos / tests.\n *\n * import { createMockTransport } from '@mahmulp/feedback-sdk/mock'\n *\n * No persistence, no network. Useful before the API is wired up.\n */\n\nexport interface MockTransportOptions {\n /** Optional initial feedback records (e.g. seeded from a fixture). */\n initial?: Feedback[];\n /** Override id generation (defaults to `fb_<timestamp>_<rand>`). */\n generateId?: () => string;\n /** Optional fake latency in ms, applied to every call. */\n latencyMs?: number;\n}\n\nexport function createMockTransport(options: MockTransportOptions = {}): FeedbackTransport & {\n /** Direct read of the in-memory store for tests / debugging. */\n _all(): Feedback[];\n _reset(): void;\n} {\n const items: Feedback[] = options.initial ? options.initial.map(clone) : [];\n const genId = options.generateId ?? defaultGenerateId;\n const latency = options.latencyMs ?? 0;\n\n async function delay() {\n if (latency > 0) await new Promise((r) => setTimeout(r, latency));\n }\n\n return {\n async list(query: ListFeedbackQuery): Promise<ListFeedbackResult> {\n await delay();\n // When `projectId` is empty, the SDK is relying on the API to scope by\n // key — return every record. When set, scope by it.\n const filtered = items\n .filter((f) => (query.projectId ? f.projectId === query.projectId : true))\n .filter((f) => (query.pageUrl ? f.pageUrl === query.pageUrl : true))\n .filter((f) => (query.status ? f.status === query.status : true))\n .map(clone);\n return { items: filtered };\n },\n\n async create(input: CreateFeedbackInput): Promise<Feedback> {\n await delay();\n const now = new Date().toISOString();\n const id = genId();\n const fb: Feedback = {\n id,\n projectId: input.projectId,\n pageUrl: input.pageUrl,\n selector: input.selector,\n coordinates: { ...input.coordinates },\n viewport: { ...input.viewport },\n status: \"open\",\n thread: input.comment\n ? [\n {\n id: `cm_${id}_0`,\n author: { ...input.comment.author },\n body: input.comment.body,\n createdAt: now,\n },\n ]\n : [],\n createdAt: now,\n updatedAt: now,\n };\n items.push(fb);\n return clone(fb);\n },\n\n async reply(\n feedbackId: string,\n comment: { author: FeedbackAuthor; body: string }\n ): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n const now = new Date().toISOString();\n fb.thread.push({\n id: `cm_${feedbackId}_${fb.thread.length}`,\n author: { ...comment.author },\n body: comment.body,\n createdAt: now,\n });\n fb.updatedAt = now;\n return clone(fb);\n },\n\n async setStatus(feedbackId: string, status: FeedbackStatus): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.status = status;\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n async move(feedbackId: string, coordinates: FeedbackCoordinates): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.coordinates = { ...coordinates };\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n async uploadScreenshot(feedbackId: string, _blob: Blob): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.screenshotKey = `screenshots/${feedbackId}.png`;\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n _all() {\n return items.map(clone);\n },\n _reset() {\n items.length = 0;\n },\n };\n}\n\nfunction defaultGenerateId(): string {\n return `fb_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction clone<T>(value: T): T {\n // Structured clone is fine here; the records are plain JSON shapes.\n return JSON.parse(JSON.stringify(value)) as T;\n}\n"]}
1
+ {"version":3,"sources":["../src/mock.ts"],"names":[],"mappings":";AA4BO,SAAS,mBAAA,CAAoB,OAAA,GAAgC,EAAC,EAInE;AACA,EAAA,MAAM,KAAA,GAAoB,QAAQ,OAAA,GAAU,OAAA,CAAQ,QAAQ,GAAA,CAAI,KAAK,IAAI,EAAC;AAC1E,EAAA,MAAM,KAAA,GAAQ,QAAQ,UAAA,IAAc,iBAAA;AACpC,EAAA,MAAM,OAAA,GAAU,QAAQ,SAAA,IAAa,CAAA;AAErC,EAAA,eAAe,KAAA,GAAQ;AACrB,IAAA,IAAI,OAAA,GAAU,CAAA,EAAG,MAAM,IAAI,OAAA,CAAQ,CAAC,CAAA,KAAM,UAAA,CAAW,CAAA,EAAG,OAAO,CAAC,CAAA;AAAA,EAClE;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,KAAK,KAAA,EAAuD;AAChE,MAAA,MAAM,KAAA,EAAM;AAGZ,MAAA,MAAM,WAAW,KAAA,CACd,MAAA,CAAO,CAAC,CAAA,KAAO,MAAM,SAAA,GAAY,CAAA,CAAE,SAAA,KAAc,KAAA,CAAM,YAAY,IAAK,CAAA,CACxE,MAAA,CAAO,CAAC,MAAO,KAAA,CAAM,OAAA,GAAU,CAAA,CAAE,OAAA,KAAY,MAAM,OAAA,GAAU,IAAK,CAAA,CAClE,MAAA,CAAO,CAAC,CAAA,KAAO,KAAA,CAAM,MAAA,GAAS,CAAA,CAAE,WAAW,KAAA,CAAM,MAAA,GAAS,IAAK,CAAA,CAC/D,IAAI,KAAK,CAAA;AACZ,MAAA,OAAO,EAAE,OAAO,QAAA,EAAS;AAAA,IAC3B,CAAA;AAAA,IAEA,MAAM,OAAO,KAAA,EAA+C;AAC1D,MAAA,MAAM,KAAA,EAAM;AACZ,MAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,MAAA,MAAM,KAAK,KAAA,EAAM;AACjB,MAAA,MAAM,EAAA,GAAe;AAAA,QACnB,EAAA;AAAA,QACA,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,WAAA,EAAa,EAAE,GAAG,KAAA,CAAM,WAAA,EAAY;AAAA,QACpC,QAAA,EAAU,EAAE,GAAG,KAAA,CAAM,QAAA,EAAS;AAAA,QAC9B,MAAA,EAAQ,MAAA;AAAA,QACR,MAAA,EAAQ,MAAM,OAAA,GACV;AAAA,UACE;AAAA,YACE,EAAA,EAAI,MAAM,EAAE,CAAA,EAAA,CAAA;AAAA,YACZ,MAAA,EAAQ,EAAE,GAAG,KAAA,CAAM,QAAQ,MAAA,EAAO;AAAA,YAClC,IAAA,EAAM,MAAM,OAAA,CAAQ,IAAA;AAAA,YACpB,SAAA,EAAW;AAAA;AACb,YAEF,EAAC;AAAA,QACL,SAAA,EAAW,GAAA;AAAA,QACX,SAAA,EAAW;AAAA,OACb;AACA,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,MAAA,OAAO,MAAM,EAAE,CAAA;AAAA,IACjB,CAAA;AAAA,IAEA,MAAM,KAAA,CACJ,UAAA,EACA,OAAA,EACmB;AACnB,MAAA,MAAM,KAAA,EAAM;AACZ,MAAA,MAAM,KAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,UAAU,CAAA;AAChD,MAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuB,UAAU,CAAA,CAAE,CAAA;AAC5D,MAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,MAAA,EAAA,CAAG,OAAO,IAAA,CAAK;AAAA,QACb,IAAI,CAAA,GAAA,EAAM,UAAU,CAAA,CAAA,EAAI,EAAA,CAAG,OAAO,MAAM,CAAA,CAAA;AAAA,QACxC,MAAA,EAAQ,EAAE,GAAG,OAAA,CAAQ,MAAA,EAAO;AAAA,QAC5B,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,SAAA,EAAW;AAAA,OACZ,CAAA;AACD,MAAA,EAAA,CAAG,SAAA,GAAY,GAAA;AACf,MAAA,OAAO,MAAM,EAAE,CAAA;AAAA,IACjB,CAAA;AAAA,IAEA,MAAM,SAAA,CAAU,UAAA,EAAoB,MAAA,EAA2C;AAC7E,MAAA,MAAM,KAAA,EAAM;AACZ,MAAA,MAAM,KAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,UAAU,CAAA;AAChD,MAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuB,UAAU,CAAA,CAAE,CAAA;AAC5D,MAAA,EAAA,CAAG,MAAA,GAAS,MAAA;AACZ,MAAA,EAAA,CAAG,SAAA,GAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACtC,MAAA,OAAO,MAAM,EAAE,CAAA;AAAA,IACjB,CAAA;AAAA,IAEA,MAAM,IAAA,CAAK,UAAA,EAAoB,WAAA,EAAqD;AAClF,MAAA,MAAM,KAAA,EAAM;AACZ,MAAA,MAAM,KAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,UAAU,CAAA;AAChD,MAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuB,UAAU,CAAA,CAAE,CAAA;AAC5D,MAAA,EAAA,CAAG,WAAA,GAAc,EAAE,GAAG,WAAA,EAAY;AAClC,MAAA,EAAA,CAAG,SAAA,GAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACtC,MAAA,OAAO,MAAM,EAAE,CAAA;AAAA,IACjB,CAAA;AAAA,IAEA,MAAM,gBAAA,CAAiB,UAAA,EAAoB,KAAA,EAAgC;AACzE,MAAA,MAAM,KAAA,EAAM;AACZ,MAAA,MAAM,KAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,UAAU,CAAA;AAChD,MAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuB,UAAU,CAAA,CAAE,CAAA;AAC5D,MAAA,EAAA,CAAG,aAAA,GAAgB,eAAe,UAAU,CAAA,IAAA,CAAA;AAC5C,MAAA,EAAA,CAAG,SAAA,GAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACtC,MAAA,OAAO,MAAM,EAAE,CAAA;AAAA,IACjB,CAAA;AAAA,IAEA,IAAA,GAAO;AACL,MAAA,OAAO,KAAA,CAAM,IAAI,KAAK,CAAA;AAAA,IACxB,CAAA;AAAA,IACA,MAAA,GAAS;AACP,MAAA,KAAA,CAAM,MAAA,GAAS,CAAA;AAAA,IACjB;AAAA,GACF;AACF;AAEA,SAAS,iBAAA,GAA4B;AACnC,EAAA,OAAO,MAAM,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,EAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAChF;AAEA,SAAS,MAAS,KAAA,EAAa;AAE7B,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AACzC","file":"mock.js","sourcesContent":["import type {\r\n CreateFeedbackInput,\r\n Feedback,\r\n FeedbackAuthor,\r\n FeedbackCoordinates,\r\n FeedbackStatus,\r\n FeedbackTransport,\r\n ListFeedbackQuery,\r\n ListFeedbackResult,\r\n} from \"./types.js\";\r\n\r\n/**\r\n * In-memory transport for local development / demos / tests.\r\n *\r\n * import { createMockTransport } from '@mahmulp/feedback-sdk/mock'\r\n *\r\n * No persistence, no network. Useful before the API is wired up.\r\n */\r\n\r\nexport interface MockTransportOptions {\r\n /** Optional initial feedback records (e.g. seeded from a fixture). */\r\n initial?: Feedback[];\r\n /** Override id generation (defaults to `fb_<timestamp>_<rand>`). */\r\n generateId?: () => string;\r\n /** Optional fake latency in ms, applied to every call. */\r\n latencyMs?: number;\r\n}\r\n\r\nexport function createMockTransport(options: MockTransportOptions = {}): FeedbackTransport & {\r\n /** Direct read of the in-memory store for tests / debugging. */\r\n _all(): Feedback[];\r\n _reset(): void;\r\n} {\r\n const items: Feedback[] = options.initial ? options.initial.map(clone) : [];\r\n const genId = options.generateId ?? defaultGenerateId;\r\n const latency = options.latencyMs ?? 0;\r\n\r\n async function delay() {\r\n if (latency > 0) await new Promise((r) => setTimeout(r, latency));\r\n }\r\n\r\n return {\r\n async list(query: ListFeedbackQuery): Promise<ListFeedbackResult> {\r\n await delay();\r\n // When `projectId` is empty, the SDK is relying on the API to scope by\r\n // key — return every record. When set, scope by it.\r\n const filtered = items\r\n .filter((f) => (query.projectId ? f.projectId === query.projectId : true))\r\n .filter((f) => (query.pageUrl ? f.pageUrl === query.pageUrl : true))\r\n .filter((f) => (query.status ? f.status === query.status : true))\r\n .map(clone);\r\n return { items: filtered };\r\n },\r\n\r\n async create(input: CreateFeedbackInput): Promise<Feedback> {\r\n await delay();\r\n const now = new Date().toISOString();\r\n const id = genId();\r\n const fb: Feedback = {\r\n id,\r\n projectId: input.projectId,\r\n pageUrl: input.pageUrl,\r\n selector: input.selector,\r\n coordinates: { ...input.coordinates },\r\n viewport: { ...input.viewport },\r\n status: \"open\",\r\n thread: input.comment\r\n ? [\r\n {\r\n id: `cm_${id}_0`,\r\n author: { ...input.comment.author },\r\n body: input.comment.body,\r\n createdAt: now,\r\n },\r\n ]\r\n : [],\r\n createdAt: now,\r\n updatedAt: now,\r\n };\r\n items.push(fb);\r\n return clone(fb);\r\n },\r\n\r\n async reply(\r\n feedbackId: string,\r\n comment: { author: FeedbackAuthor; body: string }\r\n ): Promise<Feedback> {\r\n await delay();\r\n const fb = items.find((f) => f.id === feedbackId);\r\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\r\n const now = new Date().toISOString();\r\n fb.thread.push({\r\n id: `cm_${feedbackId}_${fb.thread.length}`,\r\n author: { ...comment.author },\r\n body: comment.body,\r\n createdAt: now,\r\n });\r\n fb.updatedAt = now;\r\n return clone(fb);\r\n },\r\n\r\n async setStatus(feedbackId: string, status: FeedbackStatus): Promise<Feedback> {\r\n await delay();\r\n const fb = items.find((f) => f.id === feedbackId);\r\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\r\n fb.status = status;\r\n fb.updatedAt = new Date().toISOString();\r\n return clone(fb);\r\n },\r\n\r\n async move(feedbackId: string, coordinates: FeedbackCoordinates): Promise<Feedback> {\r\n await delay();\r\n const fb = items.find((f) => f.id === feedbackId);\r\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\r\n fb.coordinates = { ...coordinates };\r\n fb.updatedAt = new Date().toISOString();\r\n return clone(fb);\r\n },\r\n\r\n async uploadScreenshot(feedbackId: string, _blob: Blob): Promise<Feedback> {\r\n await delay();\r\n const fb = items.find((f) => f.id === feedbackId);\r\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\r\n fb.screenshotKey = `screenshots/${feedbackId}.png`;\r\n fb.updatedAt = new Date().toISOString();\r\n return clone(fb);\r\n },\r\n\r\n _all() {\r\n return items.map(clone);\r\n },\r\n _reset() {\r\n items.length = 0;\r\n },\r\n };\r\n}\r\n\r\nfunction defaultGenerateId(): string {\r\n return `fb_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\r\n}\r\n\r\nfunction clone<T>(value: T): T {\r\n // Structured clone is fine here; the records are plain JSON shapes.\r\n return JSON.parse(JSON.stringify(value)) as T;\r\n}\r\n"]}