experiments in a post-browser web
1/**
2 * Storage Adapter Interface
3 *
4 * Every adapter implements this async interface.
5 * SQLite adapters wrap sync calls in Promises for uniformity.
6 *
7 * Item shape:
8 * @typedef {Object} Item
9 * @property {string} id
10 * @property {string} type - 'url' | 'text' | 'tagset' | 'image'
11 * @property {string|null} content
12 * @property {string|null} metadata - JSON string
13 * @property {string} syncId
14 * @property {string} syncSource
15 * @property {number} syncedAt - Unix ms
16 * @property {number} createdAt - Unix ms
17 * @property {number} updatedAt - Unix ms
18 * @property {number} deletedAt - Unix ms, 0 = active
19 *
20 * Tag shape:
21 * @typedef {Object} Tag
22 * @property {string|number} id
23 * @property {string} name
24 * @property {number} frequency
25 * @property {number} lastUsed - Unix ms
26 * @property {number} frecencyScore
27 * @property {number} createdAt - Unix ms
28 * @property {number} updatedAt - Unix ms
29 *
30 * Filter shape:
31 * @typedef {Object} ItemFilter
32 * @property {string} [type]
33 * @property {number} [since] - Unix ms, return items with updatedAt > since
34 * @property {boolean} [includeDeleted]
35 *
36 * @interface StorageAdapter
37 */
38
39/**
40 * @method open
41 * @param {Object} [config]
42 * @returns {Promise<void>}
43 */
44
45/**
46 * @method close
47 * @returns {Promise<void>}
48 */
49
50// ==================== Items ====================
51
52/**
53 * @method getItem
54 * @param {string} id
55 * @returns {Promise<Item|null>} - null if not found or soft-deleted
56 */
57
58/**
59 * @method getItems
60 * @param {ItemFilter} [filter]
61 * @returns {Promise<Item[]>}
62 */
63
64/**
65 * @method insertItem
66 * @param {Item} item - Complete item object with id already assigned
67 * @returns {Promise<void>}
68 */
69
70/**
71 * @method updateItem
72 * @param {string} id
73 * @param {Partial<Item>} fields - Only provided fields are updated (undefined values skipped)
74 * @returns {Promise<void>}
75 */
76
77/**
78 * @method deleteItem
79 * @param {string} id - Soft delete: sets deletedAt
80 * @returns {Promise<void>}
81 */
82
83/**
84 * @method hardDeleteItem
85 * @param {string} id - Physical delete from storage
86 * @returns {Promise<void>}
87 */
88
89// ==================== Tags ====================
90
91/**
92 * @method getTag
93 * @param {string|number} id
94 * @returns {Promise<Tag|null>}
95 */
96
97/**
98 * @method getTagByName
99 * @param {string} name - Case-insensitive match
100 * @returns {Promise<Tag|null>}
101 */
102
103/**
104 * @method insertTag
105 * @param {Tag} tag - Complete tag object with id already assigned
106 * @returns {Promise<void>}
107 */
108
109/**
110 * @method updateTag
111 * @param {string|number} id
112 * @param {Partial<Tag>} fields - Only provided fields are updated
113 * @returns {Promise<void>}
114 */
115
116// ==================== Item-Tags ====================
117
118/**
119 * @method getItemTags
120 * @param {string} itemId
121 * @returns {Promise<Tag[]>}
122 */
123
124/**
125 * @method getItemsByTag
126 * @param {string|number} tagId
127 * @returns {Promise<Item[]>}
128 */
129
130/**
131 * @method tagItem
132 * @param {string} itemId
133 * @param {string|number} tagId
134 * @returns {Promise<void>}
135 */
136
137/**
138 * @method untagItem
139 * @param {string} itemId
140 * @param {string|number} tagId
141 * @returns {Promise<void>}
142 */
143
144/**
145 * @method clearItemTags
146 * @param {string} itemId - Remove all tag associations for this item
147 * @returns {Promise<void>}
148 */
149
150// ==================== Settings ====================
151
152/**
153 * @method getSetting
154 * @param {string} key
155 * @returns {Promise<string|null>}
156 */
157
158/**
159 * @method setSetting
160 * @param {string} key
161 * @param {string} value
162 * @returns {Promise<void>}
163 */
164
165// ==================== Query Helpers ====================
166
167/**
168 * @method findItemBySyncId
169 * @param {string} syncId - Checks both item.id and item.syncId fields
170 * @returns {Promise<Item|null>}
171 */
172
173/**
174 * @method getAllTags
175 * @returns {Promise<Tag[]>}
176 */