@aigne/afs-index 1.12.0-beta.5
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/LICENSE.md +26 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs +11 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs +10 -0
- package/dist/backend/d1-index-backend.cjs +656 -0
- package/dist/backend/d1-index-backend.d.cts +149 -0
- package/dist/backend/d1-index-backend.d.cts.map +1 -0
- package/dist/backend/d1-index-backend.d.mts +149 -0
- package/dist/backend/d1-index-backend.d.mts.map +1 -0
- package/dist/backend/d1-index-backend.mjs +657 -0
- package/dist/backend/d1-index-backend.mjs.map +1 -0
- package/dist/backend/d1-vector-backend.cjs +83 -0
- package/dist/backend/d1-vector-backend.d.cts +21 -0
- package/dist/backend/d1-vector-backend.d.cts.map +1 -0
- package/dist/backend/d1-vector-backend.d.mts +21 -0
- package/dist/backend/d1-vector-backend.d.mts.map +1 -0
- package/dist/backend/d1-vector-backend.mjs +84 -0
- package/dist/backend/d1-vector-backend.mjs.map +1 -0
- package/dist/backend/memory-backend.cjs +304 -0
- package/dist/backend/memory-backend.d.cts +66 -0
- package/dist/backend/memory-backend.d.cts.map +1 -0
- package/dist/backend/memory-backend.d.mts +66 -0
- package/dist/backend/memory-backend.d.mts.map +1 -0
- package/dist/backend/memory-backend.mjs +305 -0
- package/dist/backend/memory-backend.mjs.map +1 -0
- package/dist/backend/prefix-range.cjs +25 -0
- package/dist/backend/prefix-range.mjs +25 -0
- package/dist/backend/prefix-range.mjs.map +1 -0
- package/dist/backend/schema.cjs +187 -0
- package/dist/backend/schema.mjs +188 -0
- package/dist/backend/schema.mjs.map +1 -0
- package/dist/backend/sqlite-backend.cjs +889 -0
- package/dist/backend/sqlite-backend.d.cts +96 -0
- package/dist/backend/sqlite-backend.d.cts.map +1 -0
- package/dist/backend/sqlite-backend.d.mts +96 -0
- package/dist/backend/sqlite-backend.d.mts.map +1 -0
- package/dist/backend/sqlite-backend.mjs +890 -0
- package/dist/backend/sqlite-backend.mjs.map +1 -0
- package/dist/backend/types.d.cts +209 -0
- package/dist/backend/types.d.cts.map +1 -0
- package/dist/backend/types.d.mts +209 -0
- package/dist/backend/types.d.mts.map +1 -0
- package/dist/backend/upstash-vector-backend.cjs +98 -0
- package/dist/backend/upstash-vector-backend.d.cts +21 -0
- package/dist/backend/upstash-vector-backend.d.cts.map +1 -0
- package/dist/backend/upstash-vector-backend.d.mts +21 -0
- package/dist/backend/upstash-vector-backend.d.mts.map +1 -0
- package/dist/backend/upstash-vector-backend.mjs +98 -0
- package/dist/backend/upstash-vector-backend.mjs.map +1 -0
- package/dist/backend/vector-backend.d.cts +29 -0
- package/dist/backend/vector-backend.d.cts.map +1 -0
- package/dist/backend/vector-backend.d.mts +29 -0
- package/dist/backend/vector-backend.d.mts.map +1 -0
- package/dist/dirty-queue.d.cts +41 -0
- package/dist/dirty-queue.d.cts.map +1 -0
- package/dist/dirty-queue.d.mts +41 -0
- package/dist/dirty-queue.d.mts.map +1 -0
- package/dist/embed.cjs +45 -0
- package/dist/embed.d.cts +20 -0
- package/dist/embed.d.cts.map +1 -0
- package/dist/embed.d.mts +20 -0
- package/dist/embed.d.mts.map +1 -0
- package/dist/embed.mjs +46 -0
- package/dist/embed.mjs.map +1 -0
- package/dist/extraction/defaults.cjs +242 -0
- package/dist/extraction/defaults.d.cts +14 -0
- package/dist/extraction/defaults.d.cts.map +1 -0
- package/dist/extraction/defaults.d.mts +14 -0
- package/dist/extraction/defaults.d.mts.map +1 -0
- package/dist/extraction/defaults.mjs +242 -0
- package/dist/extraction/defaults.mjs.map +1 -0
- package/dist/extraction/field-map.cjs +162 -0
- package/dist/extraction/field-map.d.cts +70 -0
- package/dist/extraction/field-map.d.cts.map +1 -0
- package/dist/extraction/field-map.d.mts +70 -0
- package/dist/extraction/field-map.d.mts.map +1 -0
- package/dist/extraction/field-map.mjs +157 -0
- package/dist/extraction/field-map.mjs.map +1 -0
- package/dist/extraction/manager.cjs +74 -0
- package/dist/extraction/manager.d.cts +47 -0
- package/dist/extraction/manager.d.cts.map +1 -0
- package/dist/extraction/manager.d.mts +47 -0
- package/dist/extraction/manager.d.mts.map +1 -0
- package/dist/extraction/manager.mjs +74 -0
- package/dist/extraction/manager.mjs.map +1 -0
- package/dist/extraction/path-anchors.cjs +86 -0
- package/dist/extraction/path-anchors.d.cts +72 -0
- package/dist/extraction/path-anchors.d.cts.map +1 -0
- package/dist/extraction/path-anchors.d.mts +72 -0
- package/dist/extraction/path-anchors.d.mts.map +1 -0
- package/dist/extraction/path-anchors.mjs +86 -0
- package/dist/extraction/path-anchors.mjs.map +1 -0
- package/dist/follower-scheduler.cjs +92 -0
- package/dist/follower-scheduler.d.cts +58 -0
- package/dist/follower-scheduler.d.cts.map +1 -0
- package/dist/follower-scheduler.d.mts +58 -0
- package/dist/follower-scheduler.d.mts.map +1 -0
- package/dist/follower-scheduler.mjs +92 -0
- package/dist/follower-scheduler.mjs.map +1 -0
- package/dist/follower.cjs +577 -0
- package/dist/follower.d.cts +241 -0
- package/dist/follower.d.cts.map +1 -0
- package/dist/follower.d.mts +241 -0
- package/dist/follower.d.mts.map +1 -0
- package/dist/follower.mjs +571 -0
- package/dist/follower.mjs.map +1 -0
- package/dist/index-provider.cjs +1166 -0
- package/dist/index-provider.d.cts +175 -0
- package/dist/index-provider.d.cts.map +1 -0
- package/dist/index-provider.d.mts +175 -0
- package/dist/index-provider.d.mts.map +1 -0
- package/dist/index-provider.mjs +1167 -0
- package/dist/index-provider.mjs.map +1 -0
- package/dist/index.cjs +53 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.mts +22 -0
- package/dist/index.mjs +20 -0
- package/dist/keys/exact.cjs +20 -0
- package/dist/keys/exact.mjs +20 -0
- package/dist/keys/exact.mjs.map +1 -0
- package/dist/keys/location.cjs +13 -0
- package/dist/keys/location.mjs +13 -0
- package/dist/keys/location.mjs.map +1 -0
- package/dist/keys/normalized.cjs +62 -0
- package/dist/keys/normalized.mjs +63 -0
- package/dist/keys/normalized.mjs.map +1 -0
- package/dist/keys/person.cjs +15 -0
- package/dist/keys/person.mjs +15 -0
- package/dist/keys/person.mjs.map +1 -0
- package/dist/keys/registry.cjs +45 -0
- package/dist/keys/registry.d.cts +15 -0
- package/dist/keys/registry.d.cts.map +1 -0
- package/dist/keys/registry.d.mts +15 -0
- package/dist/keys/registry.d.mts.map +1 -0
- package/dist/keys/registry.mjs +46 -0
- package/dist/keys/registry.mjs.map +1 -0
- package/dist/keys/time.cjs +128 -0
- package/dist/keys/time.mjs +128 -0
- package/dist/keys/time.mjs.map +1 -0
- package/dist/keys/topic.cjs +23 -0
- package/dist/keys/topic.mjs +23 -0
- package/dist/keys/topic.mjs.map +1 -0
- package/dist/manifest-index.cjs +29 -0
- package/dist/manifest-index.d.cts +24 -0
- package/dist/manifest-index.d.cts.map +1 -0
- package/dist/manifest-index.d.mts +24 -0
- package/dist/manifest-index.d.mts.map +1 -0
- package/dist/manifest-index.mjs +28 -0
- package/dist/manifest-index.mjs.map +1 -0
- package/dist/offline-rebuild.cjs +48 -0
- package/dist/offline-rebuild.d.cts +57 -0
- package/dist/offline-rebuild.d.cts.map +1 -0
- package/dist/offline-rebuild.d.mts +57 -0
- package/dist/offline-rebuild.d.mts.map +1 -0
- package/dist/offline-rebuild.mjs +49 -0
- package/dist/offline-rebuild.mjs.map +1 -0
- package/dist/query/engine.cjs +433 -0
- package/dist/query/engine.d.cts +34 -0
- package/dist/query/engine.d.cts.map +1 -0
- package/dist/query/engine.d.mts +34 -0
- package/dist/query/engine.d.mts.map +1 -0
- package/dist/query/engine.mjs +433 -0
- package/dist/query/engine.mjs.map +1 -0
- package/dist/query/limits.cjs +12 -0
- package/dist/query/limits.mjs +12 -0
- package/dist/query/limits.mjs.map +1 -0
- package/dist/text/cjk.cjs +30 -0
- package/dist/text/cjk.d.cts +24 -0
- package/dist/text/cjk.d.cts.map +1 -0
- package/dist/text/cjk.d.mts +24 -0
- package/dist/text/cjk.d.mts.map +1 -0
- package/dist/text/cjk.mjs +30 -0
- package/dist/text/cjk.mjs.map +1 -0
- package/dist/text/fts.cjs +244 -0
- package/dist/text/fts.mjs +245 -0
- package/dist/text/fts.mjs.map +1 -0
- package/dist/text/host.cjs +39 -0
- package/dist/text/host.mjs +38 -0
- package/dist/text/host.mjs.map +1 -0
- package/dist/types.cjs +44 -0
- package/dist/types.d.cts +393 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +393 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +42 -0
- package/dist/types.mjs.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/extraction/defaults.ts
|
|
3
|
+
const MIME_CATEGORIES = {
|
|
4
|
+
image: "image",
|
|
5
|
+
video: "video",
|
|
6
|
+
audio: "audio",
|
|
7
|
+
text: "document",
|
|
8
|
+
application: "document"
|
|
9
|
+
};
|
|
10
|
+
const EXT_MIME = {
|
|
11
|
+
".jpg": {
|
|
12
|
+
mime: "image/jpeg",
|
|
13
|
+
category: "image"
|
|
14
|
+
},
|
|
15
|
+
".jpeg": {
|
|
16
|
+
mime: "image/jpeg",
|
|
17
|
+
category: "image"
|
|
18
|
+
},
|
|
19
|
+
".png": {
|
|
20
|
+
mime: "image/png",
|
|
21
|
+
category: "image"
|
|
22
|
+
},
|
|
23
|
+
".gif": {
|
|
24
|
+
mime: "image/gif",
|
|
25
|
+
category: "image"
|
|
26
|
+
},
|
|
27
|
+
".webp": {
|
|
28
|
+
mime: "image/webp",
|
|
29
|
+
category: "image"
|
|
30
|
+
},
|
|
31
|
+
".svg": {
|
|
32
|
+
mime: "image/svg+xml",
|
|
33
|
+
category: "image"
|
|
34
|
+
},
|
|
35
|
+
".mp4": {
|
|
36
|
+
mime: "video/mp4",
|
|
37
|
+
category: "video"
|
|
38
|
+
},
|
|
39
|
+
".mov": {
|
|
40
|
+
mime: "video/quicktime",
|
|
41
|
+
category: "video"
|
|
42
|
+
},
|
|
43
|
+
".mp3": {
|
|
44
|
+
mime: "audio/mpeg",
|
|
45
|
+
category: "audio"
|
|
46
|
+
},
|
|
47
|
+
".wav": {
|
|
48
|
+
mime: "audio/wav",
|
|
49
|
+
category: "audio"
|
|
50
|
+
},
|
|
51
|
+
".md": {
|
|
52
|
+
mime: "text/markdown",
|
|
53
|
+
category: "document"
|
|
54
|
+
},
|
|
55
|
+
".txt": {
|
|
56
|
+
mime: "text/plain",
|
|
57
|
+
category: "document"
|
|
58
|
+
},
|
|
59
|
+
".pdf": {
|
|
60
|
+
mime: "application/pdf",
|
|
61
|
+
category: "document"
|
|
62
|
+
},
|
|
63
|
+
".json": {
|
|
64
|
+
mime: "application/json",
|
|
65
|
+
category: "document"
|
|
66
|
+
},
|
|
67
|
+
".yaml": {
|
|
68
|
+
mime: "application/yaml",
|
|
69
|
+
category: "document"
|
|
70
|
+
},
|
|
71
|
+
".yml": {
|
|
72
|
+
mime: "application/yaml",
|
|
73
|
+
category: "document"
|
|
74
|
+
},
|
|
75
|
+
".html": {
|
|
76
|
+
mime: "text/html",
|
|
77
|
+
category: "document"
|
|
78
|
+
},
|
|
79
|
+
".css": {
|
|
80
|
+
mime: "text/css",
|
|
81
|
+
category: "document"
|
|
82
|
+
},
|
|
83
|
+
".js": {
|
|
84
|
+
mime: "application/javascript",
|
|
85
|
+
category: "code"
|
|
86
|
+
},
|
|
87
|
+
".ts": {
|
|
88
|
+
mime: "application/typescript",
|
|
89
|
+
category: "code"
|
|
90
|
+
},
|
|
91
|
+
".py": {
|
|
92
|
+
mime: "text/x-python",
|
|
93
|
+
category: "code"
|
|
94
|
+
},
|
|
95
|
+
".rs": {
|
|
96
|
+
mime: "text/x-rust",
|
|
97
|
+
category: "code"
|
|
98
|
+
},
|
|
99
|
+
".go": {
|
|
100
|
+
mime: "text/x-go",
|
|
101
|
+
category: "code"
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
function mimeCategory(mime) {
|
|
105
|
+
return MIME_CATEGORIES[mime.split("/")[0] ?? ""] ?? "other";
|
|
106
|
+
}
|
|
107
|
+
function fileExtension(path) {
|
|
108
|
+
const lastDot = path.lastIndexOf(".");
|
|
109
|
+
if (lastDot === -1) return "";
|
|
110
|
+
return path.slice(lastDot).toLowerCase();
|
|
111
|
+
}
|
|
112
|
+
function fileName(path) {
|
|
113
|
+
const segments = path.split("/").filter(Boolean);
|
|
114
|
+
return segments[segments.length - 1] ?? path;
|
|
115
|
+
}
|
|
116
|
+
const BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz";
|
|
117
|
+
function encodeGeohash(lat, lon, precision = 7) {
|
|
118
|
+
let minLat = -90;
|
|
119
|
+
let maxLat = 90;
|
|
120
|
+
let minLon = -180;
|
|
121
|
+
let maxLon = 180;
|
|
122
|
+
let hash = "";
|
|
123
|
+
let bit = 0;
|
|
124
|
+
let ch = 0;
|
|
125
|
+
let isLon = true;
|
|
126
|
+
while (hash.length < precision) {
|
|
127
|
+
if (isLon) {
|
|
128
|
+
const mid = (minLon + maxLon) / 2;
|
|
129
|
+
if (lon >= mid) {
|
|
130
|
+
ch |= 1 << 4 - bit;
|
|
131
|
+
minLon = mid;
|
|
132
|
+
} else maxLon = mid;
|
|
133
|
+
} else {
|
|
134
|
+
const mid = (minLat + maxLat) / 2;
|
|
135
|
+
if (lat >= mid) {
|
|
136
|
+
ch |= 1 << 4 - bit;
|
|
137
|
+
minLat = mid;
|
|
138
|
+
} else maxLat = mid;
|
|
139
|
+
}
|
|
140
|
+
isLon = !isLon;
|
|
141
|
+
bit++;
|
|
142
|
+
if (bit === 5) {
|
|
143
|
+
hash += BASE32[ch];
|
|
144
|
+
bit = 0;
|
|
145
|
+
ch = 0;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return hash;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Extract anchors and summary from AFS entry metadata.
|
|
152
|
+
*
|
|
153
|
+
* @param path - The entry path
|
|
154
|
+
* @param meta - The entry metadata (from AFSEntry.meta)
|
|
155
|
+
* @returns ExtractionResult or null if nothing useful can be extracted
|
|
156
|
+
*/
|
|
157
|
+
function extractFromMeta(path, meta) {
|
|
158
|
+
if (!meta) return null;
|
|
159
|
+
if (meta.kind === "afs:directory") return null;
|
|
160
|
+
const anchors = [];
|
|
161
|
+
const timeAnchor = extractTimeAnchor(meta);
|
|
162
|
+
if (timeAnchor) anchors.push(timeAnchor);
|
|
163
|
+
const locationAnchor = extractLocationAnchor(meta);
|
|
164
|
+
if (locationAnchor) anchors.push(locationAnchor);
|
|
165
|
+
const contentTypeAnchor = extractContentTypeAnchor(path, meta);
|
|
166
|
+
if (contentTypeAnchor) anchors.push(contentTypeAnchor);
|
|
167
|
+
return {
|
|
168
|
+
anchors,
|
|
169
|
+
summary: buildSummary(path, meta)
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function extractTimeAnchor(meta) {
|
|
173
|
+
const exifDate = meta.exif?.DateTimeOriginal;
|
|
174
|
+
if (exifDate) return {
|
|
175
|
+
type: "time",
|
|
176
|
+
confidence: 1,
|
|
177
|
+
timestamp: exifDate
|
|
178
|
+
};
|
|
179
|
+
const createdAt = meta.createdAt;
|
|
180
|
+
if (createdAt) return {
|
|
181
|
+
type: "time",
|
|
182
|
+
confidence: .9,
|
|
183
|
+
timestamp: createdAt
|
|
184
|
+
};
|
|
185
|
+
const updatedAt = meta.updatedAt;
|
|
186
|
+
if (updatedAt) return {
|
|
187
|
+
type: "time",
|
|
188
|
+
confidence: .7,
|
|
189
|
+
timestamp: updatedAt
|
|
190
|
+
};
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
function extractLocationAnchor(meta) {
|
|
194
|
+
const exif = meta.exif;
|
|
195
|
+
if (!exif) return null;
|
|
196
|
+
const lat = exif.GPSLatitude;
|
|
197
|
+
const lon = exif.GPSLongitude;
|
|
198
|
+
if (lat == null || lon == null) return null;
|
|
199
|
+
return {
|
|
200
|
+
type: "location",
|
|
201
|
+
confidence: .95,
|
|
202
|
+
geohash: encodeGeohash(lat, lon)
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function extractContentTypeAnchor(path, meta) {
|
|
206
|
+
const mime = meta.mime;
|
|
207
|
+
if (mime) return {
|
|
208
|
+
type: "content-type",
|
|
209
|
+
confidence: 1,
|
|
210
|
+
mime,
|
|
211
|
+
category: mimeCategory(mime)
|
|
212
|
+
};
|
|
213
|
+
const inferred = EXT_MIME[fileExtension(path)];
|
|
214
|
+
if (inferred) return {
|
|
215
|
+
type: "content-type",
|
|
216
|
+
confidence: .8,
|
|
217
|
+
mime: inferred.mime,
|
|
218
|
+
category: inferred.category
|
|
219
|
+
};
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
function buildSummary(path, meta) {
|
|
223
|
+
const parts = [];
|
|
224
|
+
const name = fileName(path);
|
|
225
|
+
parts.push(name);
|
|
226
|
+
const description = meta.description;
|
|
227
|
+
if (description) parts.push(description);
|
|
228
|
+
const mime = meta.mime;
|
|
229
|
+
if (mime) parts.push(mime);
|
|
230
|
+
const size = meta.size;
|
|
231
|
+
if (size != null) parts.push(formatSize(size));
|
|
232
|
+
return parts.join(" — ");
|
|
233
|
+
}
|
|
234
|
+
function formatSize(bytes) {
|
|
235
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
236
|
+
if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
237
|
+
if (bytes < 1073741824) return `${(bytes / 1048576).toFixed(1)}MB`;
|
|
238
|
+
return `${(bytes / 1073741824).toFixed(1)}GB`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
//#endregion
|
|
242
|
+
exports.extractFromMeta = extractFromMeta;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ExtractionResult } from "../types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/extraction/defaults.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Extract anchors and summary from AFS entry metadata.
|
|
6
|
+
*
|
|
7
|
+
* @param path - The entry path
|
|
8
|
+
* @param meta - The entry metadata (from AFSEntry.meta)
|
|
9
|
+
* @returns ExtractionResult or null if nothing useful can be extracted
|
|
10
|
+
*/
|
|
11
|
+
declare function extractFromMeta(path: string, meta: Record<string, unknown> | null | undefined): ExtractionResult | null;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { extractFromMeta };
|
|
14
|
+
//# sourceMappingURL=defaults.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.cts","names":[],"sources":["../../src/extraction/defaults.ts"],"mappings":";;;;;;;;;;iBAsHgB,eAAA,CACd,IAAA,UACA,IAAA,EAAM,MAAA,uCACL,gBAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ExtractionResult } from "../types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/extraction/defaults.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Extract anchors and summary from AFS entry metadata.
|
|
6
|
+
*
|
|
7
|
+
* @param path - The entry path
|
|
8
|
+
* @param meta - The entry metadata (from AFSEntry.meta)
|
|
9
|
+
* @returns ExtractionResult or null if nothing useful can be extracted
|
|
10
|
+
*/
|
|
11
|
+
declare function extractFromMeta(path: string, meta: Record<string, unknown> | null | undefined): ExtractionResult | null;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { extractFromMeta };
|
|
14
|
+
//# sourceMappingURL=defaults.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.mts","names":[],"sources":["../../src/extraction/defaults.ts"],"mappings":";;;;;;;;;;iBAsHgB,eAAA,CACd,IAAA,UACA,IAAA,EAAM,MAAA,uCACL,gBAAA"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
//#region src/extraction/defaults.ts
|
|
2
|
+
const MIME_CATEGORIES = {
|
|
3
|
+
image: "image",
|
|
4
|
+
video: "video",
|
|
5
|
+
audio: "audio",
|
|
6
|
+
text: "document",
|
|
7
|
+
application: "document"
|
|
8
|
+
};
|
|
9
|
+
const EXT_MIME = {
|
|
10
|
+
".jpg": {
|
|
11
|
+
mime: "image/jpeg",
|
|
12
|
+
category: "image"
|
|
13
|
+
},
|
|
14
|
+
".jpeg": {
|
|
15
|
+
mime: "image/jpeg",
|
|
16
|
+
category: "image"
|
|
17
|
+
},
|
|
18
|
+
".png": {
|
|
19
|
+
mime: "image/png",
|
|
20
|
+
category: "image"
|
|
21
|
+
},
|
|
22
|
+
".gif": {
|
|
23
|
+
mime: "image/gif",
|
|
24
|
+
category: "image"
|
|
25
|
+
},
|
|
26
|
+
".webp": {
|
|
27
|
+
mime: "image/webp",
|
|
28
|
+
category: "image"
|
|
29
|
+
},
|
|
30
|
+
".svg": {
|
|
31
|
+
mime: "image/svg+xml",
|
|
32
|
+
category: "image"
|
|
33
|
+
},
|
|
34
|
+
".mp4": {
|
|
35
|
+
mime: "video/mp4",
|
|
36
|
+
category: "video"
|
|
37
|
+
},
|
|
38
|
+
".mov": {
|
|
39
|
+
mime: "video/quicktime",
|
|
40
|
+
category: "video"
|
|
41
|
+
},
|
|
42
|
+
".mp3": {
|
|
43
|
+
mime: "audio/mpeg",
|
|
44
|
+
category: "audio"
|
|
45
|
+
},
|
|
46
|
+
".wav": {
|
|
47
|
+
mime: "audio/wav",
|
|
48
|
+
category: "audio"
|
|
49
|
+
},
|
|
50
|
+
".md": {
|
|
51
|
+
mime: "text/markdown",
|
|
52
|
+
category: "document"
|
|
53
|
+
},
|
|
54
|
+
".txt": {
|
|
55
|
+
mime: "text/plain",
|
|
56
|
+
category: "document"
|
|
57
|
+
},
|
|
58
|
+
".pdf": {
|
|
59
|
+
mime: "application/pdf",
|
|
60
|
+
category: "document"
|
|
61
|
+
},
|
|
62
|
+
".json": {
|
|
63
|
+
mime: "application/json",
|
|
64
|
+
category: "document"
|
|
65
|
+
},
|
|
66
|
+
".yaml": {
|
|
67
|
+
mime: "application/yaml",
|
|
68
|
+
category: "document"
|
|
69
|
+
},
|
|
70
|
+
".yml": {
|
|
71
|
+
mime: "application/yaml",
|
|
72
|
+
category: "document"
|
|
73
|
+
},
|
|
74
|
+
".html": {
|
|
75
|
+
mime: "text/html",
|
|
76
|
+
category: "document"
|
|
77
|
+
},
|
|
78
|
+
".css": {
|
|
79
|
+
mime: "text/css",
|
|
80
|
+
category: "document"
|
|
81
|
+
},
|
|
82
|
+
".js": {
|
|
83
|
+
mime: "application/javascript",
|
|
84
|
+
category: "code"
|
|
85
|
+
},
|
|
86
|
+
".ts": {
|
|
87
|
+
mime: "application/typescript",
|
|
88
|
+
category: "code"
|
|
89
|
+
},
|
|
90
|
+
".py": {
|
|
91
|
+
mime: "text/x-python",
|
|
92
|
+
category: "code"
|
|
93
|
+
},
|
|
94
|
+
".rs": {
|
|
95
|
+
mime: "text/x-rust",
|
|
96
|
+
category: "code"
|
|
97
|
+
},
|
|
98
|
+
".go": {
|
|
99
|
+
mime: "text/x-go",
|
|
100
|
+
category: "code"
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
function mimeCategory(mime) {
|
|
104
|
+
return MIME_CATEGORIES[mime.split("/")[0] ?? ""] ?? "other";
|
|
105
|
+
}
|
|
106
|
+
function fileExtension(path) {
|
|
107
|
+
const lastDot = path.lastIndexOf(".");
|
|
108
|
+
if (lastDot === -1) return "";
|
|
109
|
+
return path.slice(lastDot).toLowerCase();
|
|
110
|
+
}
|
|
111
|
+
function fileName(path) {
|
|
112
|
+
const segments = path.split("/").filter(Boolean);
|
|
113
|
+
return segments[segments.length - 1] ?? path;
|
|
114
|
+
}
|
|
115
|
+
const BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz";
|
|
116
|
+
function encodeGeohash(lat, lon, precision = 7) {
|
|
117
|
+
let minLat = -90;
|
|
118
|
+
let maxLat = 90;
|
|
119
|
+
let minLon = -180;
|
|
120
|
+
let maxLon = 180;
|
|
121
|
+
let hash = "";
|
|
122
|
+
let bit = 0;
|
|
123
|
+
let ch = 0;
|
|
124
|
+
let isLon = true;
|
|
125
|
+
while (hash.length < precision) {
|
|
126
|
+
if (isLon) {
|
|
127
|
+
const mid = (minLon + maxLon) / 2;
|
|
128
|
+
if (lon >= mid) {
|
|
129
|
+
ch |= 1 << 4 - bit;
|
|
130
|
+
minLon = mid;
|
|
131
|
+
} else maxLon = mid;
|
|
132
|
+
} else {
|
|
133
|
+
const mid = (minLat + maxLat) / 2;
|
|
134
|
+
if (lat >= mid) {
|
|
135
|
+
ch |= 1 << 4 - bit;
|
|
136
|
+
minLat = mid;
|
|
137
|
+
} else maxLat = mid;
|
|
138
|
+
}
|
|
139
|
+
isLon = !isLon;
|
|
140
|
+
bit++;
|
|
141
|
+
if (bit === 5) {
|
|
142
|
+
hash += BASE32[ch];
|
|
143
|
+
bit = 0;
|
|
144
|
+
ch = 0;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return hash;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Extract anchors and summary from AFS entry metadata.
|
|
151
|
+
*
|
|
152
|
+
* @param path - The entry path
|
|
153
|
+
* @param meta - The entry metadata (from AFSEntry.meta)
|
|
154
|
+
* @returns ExtractionResult or null if nothing useful can be extracted
|
|
155
|
+
*/
|
|
156
|
+
function extractFromMeta(path, meta) {
|
|
157
|
+
if (!meta) return null;
|
|
158
|
+
if (meta.kind === "afs:directory") return null;
|
|
159
|
+
const anchors = [];
|
|
160
|
+
const timeAnchor = extractTimeAnchor(meta);
|
|
161
|
+
if (timeAnchor) anchors.push(timeAnchor);
|
|
162
|
+
const locationAnchor = extractLocationAnchor(meta);
|
|
163
|
+
if (locationAnchor) anchors.push(locationAnchor);
|
|
164
|
+
const contentTypeAnchor = extractContentTypeAnchor(path, meta);
|
|
165
|
+
if (contentTypeAnchor) anchors.push(contentTypeAnchor);
|
|
166
|
+
return {
|
|
167
|
+
anchors,
|
|
168
|
+
summary: buildSummary(path, meta)
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function extractTimeAnchor(meta) {
|
|
172
|
+
const exifDate = meta.exif?.DateTimeOriginal;
|
|
173
|
+
if (exifDate) return {
|
|
174
|
+
type: "time",
|
|
175
|
+
confidence: 1,
|
|
176
|
+
timestamp: exifDate
|
|
177
|
+
};
|
|
178
|
+
const createdAt = meta.createdAt;
|
|
179
|
+
if (createdAt) return {
|
|
180
|
+
type: "time",
|
|
181
|
+
confidence: .9,
|
|
182
|
+
timestamp: createdAt
|
|
183
|
+
};
|
|
184
|
+
const updatedAt = meta.updatedAt;
|
|
185
|
+
if (updatedAt) return {
|
|
186
|
+
type: "time",
|
|
187
|
+
confidence: .7,
|
|
188
|
+
timestamp: updatedAt
|
|
189
|
+
};
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
function extractLocationAnchor(meta) {
|
|
193
|
+
const exif = meta.exif;
|
|
194
|
+
if (!exif) return null;
|
|
195
|
+
const lat = exif.GPSLatitude;
|
|
196
|
+
const lon = exif.GPSLongitude;
|
|
197
|
+
if (lat == null || lon == null) return null;
|
|
198
|
+
return {
|
|
199
|
+
type: "location",
|
|
200
|
+
confidence: .95,
|
|
201
|
+
geohash: encodeGeohash(lat, lon)
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function extractContentTypeAnchor(path, meta) {
|
|
205
|
+
const mime = meta.mime;
|
|
206
|
+
if (mime) return {
|
|
207
|
+
type: "content-type",
|
|
208
|
+
confidence: 1,
|
|
209
|
+
mime,
|
|
210
|
+
category: mimeCategory(mime)
|
|
211
|
+
};
|
|
212
|
+
const inferred = EXT_MIME[fileExtension(path)];
|
|
213
|
+
if (inferred) return {
|
|
214
|
+
type: "content-type",
|
|
215
|
+
confidence: .8,
|
|
216
|
+
mime: inferred.mime,
|
|
217
|
+
category: inferred.category
|
|
218
|
+
};
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
function buildSummary(path, meta) {
|
|
222
|
+
const parts = [];
|
|
223
|
+
const name = fileName(path);
|
|
224
|
+
parts.push(name);
|
|
225
|
+
const description = meta.description;
|
|
226
|
+
if (description) parts.push(description);
|
|
227
|
+
const mime = meta.mime;
|
|
228
|
+
if (mime) parts.push(mime);
|
|
229
|
+
const size = meta.size;
|
|
230
|
+
if (size != null) parts.push(formatSize(size));
|
|
231
|
+
return parts.join(" — ");
|
|
232
|
+
}
|
|
233
|
+
function formatSize(bytes) {
|
|
234
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
235
|
+
if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
236
|
+
if (bytes < 1073741824) return `${(bytes / 1048576).toFixed(1)}MB`;
|
|
237
|
+
return `${(bytes / 1073741824).toFixed(1)}GB`;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//#endregion
|
|
241
|
+
export { extractFromMeta };
|
|
242
|
+
//# sourceMappingURL=defaults.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.mjs","names":[],"sources":["../../src/extraction/defaults.ts"],"sourcesContent":["/**\n * Default metadata-based extractor — generates anchors and summary from AFS entry metadata.\n *\n * No LLM required. Extracts:\n * - Time anchor from timestamps (EXIF DateTimeOriginal > createdAt > updatedAt)\n * - Location anchor from EXIF GPS coordinates (via geohash encoding)\n * - Content-type anchor from mime type or file extension\n * - Summary from path + description + metadata\n */\nimport type { Anchor, ExtractionResult } from \"../types.js\";\n\n// --- Mime category mapping ---\n\nconst MIME_CATEGORIES: Record<string, string> = {\n image: \"image\",\n video: \"video\",\n audio: \"audio\",\n text: \"document\",\n application: \"document\",\n};\n\nconst EXT_MIME: Record<string, { mime: string; category: string }> = {\n \".jpg\": { mime: \"image/jpeg\", category: \"image\" },\n \".jpeg\": { mime: \"image/jpeg\", category: \"image\" },\n \".png\": { mime: \"image/png\", category: \"image\" },\n \".gif\": { mime: \"image/gif\", category: \"image\" },\n \".webp\": { mime: \"image/webp\", category: \"image\" },\n \".svg\": { mime: \"image/svg+xml\", category: \"image\" },\n \".mp4\": { mime: \"video/mp4\", category: \"video\" },\n \".mov\": { mime: \"video/quicktime\", category: \"video\" },\n \".mp3\": { mime: \"audio/mpeg\", category: \"audio\" },\n \".wav\": { mime: \"audio/wav\", category: \"audio\" },\n \".md\": { mime: \"text/markdown\", category: \"document\" },\n \".txt\": { mime: \"text/plain\", category: \"document\" },\n \".pdf\": { mime: \"application/pdf\", category: \"document\" },\n \".json\": { mime: \"application/json\", category: \"document\" },\n \".yaml\": { mime: \"application/yaml\", category: \"document\" },\n \".yml\": { mime: \"application/yaml\", category: \"document\" },\n \".html\": { mime: \"text/html\", category: \"document\" },\n \".css\": { mime: \"text/css\", category: \"document\" },\n \".js\": { mime: \"application/javascript\", category: \"code\" },\n \".ts\": { mime: \"application/typescript\", category: \"code\" },\n \".py\": { mime: \"text/x-python\", category: \"code\" },\n \".rs\": { mime: \"text/x-rust\", category: \"code\" },\n \".go\": { mime: \"text/x-go\", category: \"code\" },\n};\n\nfunction mimeCategory(mime: string): string {\n const primary = mime.split(\"/\")[0] ?? \"\";\n return MIME_CATEGORIES[primary] ?? \"other\";\n}\n\nfunction fileExtension(path: string): string {\n const lastDot = path.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return path.slice(lastDot).toLowerCase();\n}\n\nfunction fileName(path: string): string {\n const segments = path.split(\"/\").filter(Boolean);\n return segments[segments.length - 1] ?? path;\n}\n\n// --- Geohash encoding (basic) ---\n\nconst BASE32 = \"0123456789bcdefghjkmnpqrstuvwxyz\";\n\nfunction encodeGeohash(lat: number, lon: number, precision = 7): string {\n let minLat = -90;\n let maxLat = 90;\n let minLon = -180;\n let maxLon = 180;\n let hash = \"\";\n let bit = 0;\n let ch = 0;\n let isLon = true;\n\n while (hash.length < precision) {\n if (isLon) {\n const mid = (minLon + maxLon) / 2;\n if (lon >= mid) {\n ch |= 1 << (4 - bit);\n minLon = mid;\n } else {\n maxLon = mid;\n }\n } else {\n const mid = (minLat + maxLat) / 2;\n if (lat >= mid) {\n ch |= 1 << (4 - bit);\n minLat = mid;\n } else {\n maxLat = mid;\n }\n }\n\n isLon = !isLon;\n bit++;\n\n if (bit === 5) {\n hash += BASE32[ch];\n bit = 0;\n ch = 0;\n }\n }\n\n return hash;\n}\n\n// --- Core extraction ---\n\n/**\n * Extract anchors and summary from AFS entry metadata.\n *\n * @param path - The entry path\n * @param meta - The entry metadata (from AFSEntry.meta)\n * @returns ExtractionResult or null if nothing useful can be extracted\n */\nexport function extractFromMeta(\n path: string,\n meta: Record<string, unknown> | null | undefined,\n): ExtractionResult | null {\n if (!meta) return null;\n\n // Skip directories — only index leaf content\n const kind = meta.kind as string | undefined;\n if (kind === \"afs:directory\") return null;\n\n const anchors: Anchor[] = [];\n\n // --- Time anchor ---\n const timeAnchor = extractTimeAnchor(meta);\n if (timeAnchor) anchors.push(timeAnchor);\n\n // --- Location anchor ---\n const locationAnchor = extractLocationAnchor(meta);\n if (locationAnchor) anchors.push(locationAnchor);\n\n // --- Content-type anchor ---\n const contentTypeAnchor = extractContentTypeAnchor(path, meta);\n if (contentTypeAnchor) anchors.push(contentTypeAnchor);\n\n // --- Summary ---\n const summary = buildSummary(path, meta);\n\n return { anchors, summary };\n}\n\nfunction extractTimeAnchor(meta: Record<string, unknown>): Anchor | null {\n const exif = meta.exif as Record<string, unknown> | undefined;\n const exifDate = exif?.DateTimeOriginal as string | undefined;\n\n if (exifDate) {\n return { type: \"time\", confidence: 1.0, timestamp: exifDate };\n }\n\n const createdAt = meta.createdAt as string | undefined;\n if (createdAt) {\n return { type: \"time\", confidence: 0.9, timestamp: createdAt };\n }\n\n const updatedAt = meta.updatedAt as string | undefined;\n if (updatedAt) {\n return { type: \"time\", confidence: 0.7, timestamp: updatedAt };\n }\n\n return null;\n}\n\nfunction extractLocationAnchor(meta: Record<string, unknown>): Anchor | null {\n const exif = meta.exif as Record<string, unknown> | undefined;\n if (!exif) return null;\n\n const lat = exif.GPSLatitude as number | undefined;\n const lon = exif.GPSLongitude as number | undefined;\n\n if (lat == null || lon == null) return null;\n\n const geohash = encodeGeohash(lat, lon);\n return { type: \"location\", confidence: 0.95, geohash };\n}\n\nfunction extractContentTypeAnchor(path: string, meta: Record<string, unknown>): Anchor | null {\n const mime = meta.mime as string | undefined;\n\n if (mime) {\n return {\n type: \"content-type\",\n confidence: 1.0,\n mime,\n category: mimeCategory(mime),\n };\n }\n\n // Fallback: infer from extension\n const ext = fileExtension(path);\n const inferred = EXT_MIME[ext];\n if (inferred) {\n return {\n type: \"content-type\",\n confidence: 0.8,\n mime: inferred.mime,\n category: inferred.category,\n };\n }\n\n return null;\n}\n\nfunction buildSummary(path: string, meta: Record<string, unknown>): string {\n const parts: string[] = [];\n const name = fileName(path);\n\n parts.push(name);\n\n const description = meta.description as string | undefined;\n if (description) {\n parts.push(description);\n }\n\n const mime = meta.mime as string | undefined;\n if (mime) {\n parts.push(mime);\n }\n\n const size = meta.size as number | undefined;\n if (size != null) {\n parts.push(formatSize(size));\n }\n\n return parts.join(\" — \");\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes}B`;\n if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)}KB`;\n if (bytes < 1073741824) return `${(bytes / 1048576).toFixed(1)}MB`;\n return `${(bytes / 1073741824).toFixed(1)}GB`;\n}\n"],"mappings":"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"}
|