feedtack 1.0.1 → 1.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/chunk-3INDOI4N.js +1235 -0
- package/dist/index.d.ts +65 -3
- package/dist/index.js +85 -1
- package/dist/react/index.d.ts +2 -7
- package/dist/react/index.js +108 -999
- package/dist/{theme-BdqpMipn.d.ts → types-Cu4Oahg4.d.ts} +38 -1
- package/package.json +1 -1
- package/dist/chunk-2A5LLDLP.js +0 -237
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FeedtackAdapter, a as FeedtackPayload, b as FeedtackReply, c as FeedtackResolution, d as FeedtackFilter, e as FeedbackItem, f as FeedtackDeviceMeta, g as FeedtackPageMeta, h as FeedtackViewportMeta, i as FeedtackPinTarget } from './
|
|
2
|
-
export { A as AncestorNode,
|
|
1
|
+
import { F as FeedtackAdapter, a as FeedtackPayload, b as FeedtackReply, c as FeedtackResolution, d as FeedtackFilter, e as FeedbackItem, f as FeedtackDeviceMeta, g as FeedtackPageMeta, h as FeedtackViewportMeta, i as FeedtackPinTarget, j as FeedtackEngineOpts, k as FeedtackEngineState, l as FeedtackStateListener } from './types-Cu4Oahg4.js';
|
|
2
|
+
export { A as AncestorNode, m as FeedtackArchive, n as FeedtackBoundingRect, o as FeedtackFlushEvent, p as FeedtackPin, q as FeedtackScope, r as FeedtackSentiment, s as FeedtackTheme, t as FeedtackUser, S as SCHEMA_VERSION, u as generateId, v as themeToCSS } from './types-Cu4Oahg4.js';
|
|
3
3
|
|
|
4
4
|
/** Development adapter — logs all operations to the browser console */
|
|
5
5
|
declare class ConsoleAdapter implements FeedtackAdapter {
|
|
@@ -10,6 +10,23 @@ declare class ConsoleAdapter implements FeedtackAdapter {
|
|
|
10
10
|
loadFeedback(_filter?: FeedtackFilter): Promise<FeedbackItem[]>;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
interface DiskAdapterConfig {
|
|
14
|
+
/** Directory to store JSON files in. Default: '.feedback' */
|
|
15
|
+
directory?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Node.js adapter — persists each feedback item as a JSON file on disk */
|
|
18
|
+
declare class DiskAdapter implements FeedtackAdapter {
|
|
19
|
+
private dir;
|
|
20
|
+
constructor(config?: DiskAdapterConfig);
|
|
21
|
+
submit(payload: FeedtackPayload): Promise<void>;
|
|
22
|
+
reply(feedbackId: string, reply: Omit<FeedtackReply, 'id' | 'feedbackId'>): Promise<void>;
|
|
23
|
+
resolve(feedbackId: string, resolution: Omit<FeedtackResolution, 'feedbackId'>): Promise<void>;
|
|
24
|
+
archive(feedbackId: string, userId: string): Promise<void>;
|
|
25
|
+
loadFeedback(filter?: FeedtackFilter): Promise<FeedbackItem[]>;
|
|
26
|
+
private read;
|
|
27
|
+
private write;
|
|
28
|
+
}
|
|
29
|
+
|
|
13
30
|
interface LocalStorageAdapterConfig {
|
|
14
31
|
/** localStorage key. Default: 'feedtack' */
|
|
15
32
|
key?: string;
|
|
@@ -65,4 +82,49 @@ declare function getCSSSelector(element: Element): string;
|
|
|
65
82
|
/** Capture DOM target metadata at the clicked element */
|
|
66
83
|
declare function getTargetMeta(element: Element): FeedtackPinTarget;
|
|
67
84
|
|
|
68
|
-
|
|
85
|
+
interface FlushController {
|
|
86
|
+
flushPath: (path: string) => void;
|
|
87
|
+
clearFlushed: (path: string) => void;
|
|
88
|
+
detach: () => void;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
declare class FeedtackEngine {
|
|
92
|
+
private readonly opts;
|
|
93
|
+
private state;
|
|
94
|
+
private listeners;
|
|
95
|
+
private actionCtx;
|
|
96
|
+
private styleEl;
|
|
97
|
+
private rootEl;
|
|
98
|
+
private spaNav;
|
|
99
|
+
flushCtrl: FlushController | null;
|
|
100
|
+
private inputHandles;
|
|
101
|
+
constructor(opts: FeedtackEngineOpts);
|
|
102
|
+
getState(): Readonly<FeedtackEngineState>;
|
|
103
|
+
subscribe(listener: FeedtackStateListener): () => void;
|
|
104
|
+
private setState;
|
|
105
|
+
mount(): void;
|
|
106
|
+
destroy(): void;
|
|
107
|
+
private onNavUpdate;
|
|
108
|
+
activatePinMode(): void;
|
|
109
|
+
deactivatePinMode(): void;
|
|
110
|
+
setComment(v: string): void;
|
|
111
|
+
setSentiment(v: FeedtackEngineState['sentiment']): void;
|
|
112
|
+
setCommentError(v: boolean): void;
|
|
113
|
+
setSelectedColor(c: string): void;
|
|
114
|
+
setOpenThreadId(id: string | null): void;
|
|
115
|
+
setReplyBody(v: string): void;
|
|
116
|
+
setComposeScope(s: 'site' | 'page'): void;
|
|
117
|
+
openModal(): void;
|
|
118
|
+
closeModal(): void;
|
|
119
|
+
getCurrentScope(): "site" | "page" | "element";
|
|
120
|
+
isArchivedForUser(item: FeedbackItem): boolean;
|
|
121
|
+
hasUnread(item: FeedbackItem): boolean;
|
|
122
|
+
hasValidPins(item: FeedbackItem): boolean;
|
|
123
|
+
handleSubmit(): Promise<void>;
|
|
124
|
+
handleModalSubmit(): Promise<void>;
|
|
125
|
+
handleReply(id: string): Promise<void>;
|
|
126
|
+
handleResolve(id: string): Promise<void>;
|
|
127
|
+
handleArchive(id: string): Promise<void>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { ConsoleAdapter, DiskAdapter, type DiskAdapterConfig, FeedbackItem, FeedtackAdapter, FeedtackDeviceMeta, FeedtackEngine, FeedtackEngineOpts, FeedtackEngineState, FeedtackFilter, FeedtackPageMeta, FeedtackPayload, FeedtackPinTarget, FeedtackReply, FeedtackResolution, FeedtackStateListener, FeedtackViewportMeta, LocalStorageAdapter, type LocalStorageAdapterConfig, WebhookAdapter, type WebhookAdapterConfig, getCSSSelector, getDeviceMeta, getPageMeta, getPinCoords, getTargetMeta, getViewportMeta };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
FeedtackEngine,
|
|
2
3
|
SCHEMA_VERSION,
|
|
4
|
+
generateId,
|
|
3
5
|
getCSSSelector,
|
|
4
6
|
getDeviceMeta,
|
|
5
7
|
getPageMeta,
|
|
@@ -7,7 +9,7 @@ import {
|
|
|
7
9
|
getTargetMeta,
|
|
8
10
|
getViewportMeta,
|
|
9
11
|
themeToCSS
|
|
10
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-3INDOI4N.js";
|
|
11
13
|
|
|
12
14
|
// src/adapters/ConsoleAdapter.ts
|
|
13
15
|
var ConsoleAdapter = class {
|
|
@@ -29,6 +31,85 @@ var ConsoleAdapter = class {
|
|
|
29
31
|
}
|
|
30
32
|
};
|
|
31
33
|
|
|
34
|
+
// src/adapters/DiskAdapter.ts
|
|
35
|
+
import { readdir, readFile, writeFile, mkdir } from "fs/promises";
|
|
36
|
+
import { join } from "path";
|
|
37
|
+
var DiskAdapter = class {
|
|
38
|
+
constructor(config = {}) {
|
|
39
|
+
this.dir = config.directory ?? ".feedback";
|
|
40
|
+
}
|
|
41
|
+
async submit(payload) {
|
|
42
|
+
await mkdir(this.dir, { recursive: true });
|
|
43
|
+
const item = {
|
|
44
|
+
payload,
|
|
45
|
+
replies: [],
|
|
46
|
+
resolutions: [],
|
|
47
|
+
archives: []
|
|
48
|
+
};
|
|
49
|
+
await this.write(payload.id, item);
|
|
50
|
+
}
|
|
51
|
+
async reply(feedbackId, reply) {
|
|
52
|
+
const item = await this.read(feedbackId);
|
|
53
|
+
item.replies.push({
|
|
54
|
+
id: `r_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`,
|
|
55
|
+
feedbackId,
|
|
56
|
+
...reply
|
|
57
|
+
});
|
|
58
|
+
await this.write(feedbackId, item);
|
|
59
|
+
}
|
|
60
|
+
async resolve(feedbackId, resolution) {
|
|
61
|
+
const item = await this.read(feedbackId);
|
|
62
|
+
item.resolutions.push({ feedbackId, ...resolution });
|
|
63
|
+
await this.write(feedbackId, item);
|
|
64
|
+
}
|
|
65
|
+
async archive(feedbackId, userId) {
|
|
66
|
+
const item = await this.read(feedbackId);
|
|
67
|
+
item.archives.push({
|
|
68
|
+
feedbackId,
|
|
69
|
+
archivedBy: { id: userId, name: "", role: "" },
|
|
70
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
71
|
+
});
|
|
72
|
+
await this.write(feedbackId, item);
|
|
73
|
+
}
|
|
74
|
+
async loadFeedback(filter) {
|
|
75
|
+
let files;
|
|
76
|
+
try {
|
|
77
|
+
await mkdir(this.dir, { recursive: true });
|
|
78
|
+
files = (await readdir(this.dir)).filter((f) => f.endsWith(".json"));
|
|
79
|
+
} catch {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
const items = await Promise.all(
|
|
83
|
+
files.map(
|
|
84
|
+
async (f) => JSON.parse(
|
|
85
|
+
await readFile(join(this.dir, f), "utf-8")
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
);
|
|
89
|
+
if (!filter) return items;
|
|
90
|
+
return items.filter((item) => {
|
|
91
|
+
if (filter.scope && item.payload.scope !== filter.scope) return false;
|
|
92
|
+
if (filter.pathname && item.payload.page.pathname !== filter.pathname)
|
|
93
|
+
return false;
|
|
94
|
+
if (filter.url && item.payload.page.url !== filter.url) return false;
|
|
95
|
+
if (filter.userId && item.payload.submittedBy.id !== filter.userId)
|
|
96
|
+
return false;
|
|
97
|
+
return true;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async read(id) {
|
|
101
|
+
return JSON.parse(
|
|
102
|
+
await readFile(join(this.dir, `${id}.json`), "utf-8")
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
async write(id, item) {
|
|
106
|
+
await writeFile(
|
|
107
|
+
join(this.dir, `${id}.json`),
|
|
108
|
+
JSON.stringify(item, null, 2)
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
32
113
|
// src/adapters/LocalStorageAdapter.ts
|
|
33
114
|
var LocalStorageAdapter = class {
|
|
34
115
|
constructor(config = {}) {
|
|
@@ -135,9 +216,12 @@ var WebhookAdapter = class {
|
|
|
135
216
|
};
|
|
136
217
|
export {
|
|
137
218
|
ConsoleAdapter,
|
|
219
|
+
DiskAdapter,
|
|
220
|
+
FeedtackEngine,
|
|
138
221
|
LocalStorageAdapter,
|
|
139
222
|
SCHEMA_VERSION,
|
|
140
223
|
WebhookAdapter,
|
|
224
|
+
generateId,
|
|
141
225
|
getCSSSelector,
|
|
142
226
|
getDeviceMeta,
|
|
143
227
|
getPageMeta,
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { F as FeedtackAdapter, t as FeedtackUser, s as FeedtackTheme, e as FeedbackItem, o as FeedtackFlushEvent } from '../types-Cu4Oahg4.js';
|
|
1
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
3
|
import React from 'react';
|
|
3
|
-
import { e as FeedbackItem, F as FeedtackAdapter, p as FeedtackUser, o as FeedtackTheme } from '../theme-BdqpMipn.js';
|
|
4
4
|
|
|
5
5
|
/** Fixed palette of 6 colors for pin markers */
|
|
6
6
|
declare const PIN_PALETTE: readonly ["#ef4444", "#3b82f6", "#22c55e", "#f59e0b", "#a855f7", "#ec4899"];
|
|
@@ -18,11 +18,6 @@ interface FeedtackContextValue {
|
|
|
18
18
|
isModalOpen: boolean;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
interface FeedtackFlushEvent {
|
|
22
|
-
pathname: string;
|
|
23
|
-
items: FeedbackItem[];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
21
|
interface FeedtackClasses {
|
|
27
22
|
button?: string;
|
|
28
23
|
form?: string;
|
|
@@ -59,4 +54,4 @@ declare function FeedtackProvider({ children, adapter, currentUser, hotkey, admi
|
|
|
59
54
|
/** Hook for host app to programmatically control feedtack */
|
|
60
55
|
declare function useFeedtack(): FeedtackContextValue;
|
|
61
56
|
|
|
62
|
-
export { type FeedtackClasses, type FeedtackContextValue,
|
|
57
|
+
export { type FeedtackClasses, type FeedtackContextValue, FeedtackFlushEvent, FeedtackProvider, type FeedtackProviderProps, type FeedtackSentimentLabels, PIN_PALETTE, type PinColor, useFeedtack };
|