triiiceratops 0.9.0 → 0.9.2
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/index-bundle.d.ts +2 -0
- package/dist/index-bundle.js +2 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/plugins/image-manipulation/ImageManipulationPlugin.svelte.js +37 -72
- package/dist/plugins/image-manipulation/filters.js +6 -8
- package/dist/plugins/image-manipulation/types.js +1 -1
- package/dist/state/i18n.svelte.d.ts +3 -2
- package/dist/state/i18n.svelte.js +5 -5
- package/dist/state/manifests.svelte.js +77 -149
- package/dist/state/manifests.test.js +128 -223
- package/dist/state/viewer.svelte.d.ts +2 -2
- package/dist/state/viewer.svelte.js +374 -513
- package/dist/theme/colorUtils.js +35 -35
- package/dist/theme/colorUtils.test.js +30 -30
- package/dist/theme/themeManager.js +10 -12
- package/dist/theme/types.js +1 -1
- package/dist/types/plugin.js +18 -31
- package/dist/utils/annotationAdapter.js +80 -93
- package/dist/utils/annotationAdapter.test.js +24 -24
- package/package.json +2 -2
|
@@ -1,242 +1,147 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
23
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
-
function step(op) {
|
|
26
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
-
switch (op[0]) {
|
|
31
|
-
case 0: case 1: t = op; break;
|
|
32
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
-
default:
|
|
36
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
-
if (t[2]) _.ops.pop();
|
|
41
|
-
_.trys.pop(); continue;
|
|
42
|
-
}
|
|
43
|
-
op = body.call(thisArg, _);
|
|
44
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
49
2
|
import { ManifestsState } from "./manifests.svelte";
|
|
50
3
|
import * as manifesto from "manifesto.js";
|
|
51
4
|
// Mock manifesto.js since it's an external dependency
|
|
52
|
-
vi.mock("manifesto.js",
|
|
53
|
-
|
|
54
|
-
return
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
type: "AnnotationPage",
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
return null;
|
|
87
|
-
},
|
|
5
|
+
vi.mock("manifesto.js", async (importOriginal) => {
|
|
6
|
+
const actual = await importOriginal();
|
|
7
|
+
return {
|
|
8
|
+
...actual,
|
|
9
|
+
parseManifest: vi.fn((json) => {
|
|
10
|
+
// Minimal mock of a manifesto object
|
|
11
|
+
return {
|
|
12
|
+
getSequences: () => [
|
|
13
|
+
{
|
|
14
|
+
getCanvases: () => [{ id: "canvas1" }],
|
|
15
|
+
getCanvasById: (id) => {
|
|
16
|
+
if (id === "canvas1") {
|
|
17
|
+
return {
|
|
18
|
+
id: "canvas1",
|
|
19
|
+
__jsonld: {
|
|
20
|
+
otherContent: [
|
|
21
|
+
{
|
|
22
|
+
"@id": "http://example.org/list1",
|
|
23
|
+
"@type": "sc:AnnotationList",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
annotations: [
|
|
27
|
+
// v3 style
|
|
28
|
+
{
|
|
29
|
+
id: "http://example.org/list2",
|
|
30
|
+
type: "AnnotationPage",
|
|
31
|
+
},
|
|
32
|
+
],
|
|
88
33
|
},
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
}),
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
describe("ManifestsState", () => {
|
|
45
|
+
let state;
|
|
46
|
+
const mockFetch = vi.fn();
|
|
47
|
+
beforeEach(() => {
|
|
99
48
|
vi.stubGlobal("fetch", mockFetch);
|
|
100
49
|
state = new ManifestsState();
|
|
101
50
|
mockFetch.mockReset();
|
|
102
51
|
});
|
|
103
|
-
afterEach(
|
|
52
|
+
afterEach(() => {
|
|
104
53
|
vi.restoreAllMocks();
|
|
105
54
|
});
|
|
106
|
-
describe("fetchManifest",
|
|
107
|
-
it("should fetch and store a manifest",
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
};
|
|
116
|
-
mockFetch.mockResolvedValueOnce({
|
|
117
|
-
ok: true,
|
|
118
|
-
json: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
119
|
-
return [2 /*return*/, mockManifest];
|
|
120
|
-
}); }); },
|
|
121
|
-
});
|
|
122
|
-
return [4 /*yield*/, state.fetchManifest("http://example.org/manifest")];
|
|
123
|
-
case 1:
|
|
124
|
-
_a.sent();
|
|
125
|
-
expect(mockFetch).toHaveBeenCalledWith("http://example.org/manifest");
|
|
126
|
-
expect(state.manifests["http://example.org/manifest"]).toBeDefined();
|
|
127
|
-
expect(state.manifests["http://example.org/manifest"].json).toEqual(mockManifest);
|
|
128
|
-
expect(state.manifests["http://example.org/manifest"].isFetching).toBe(false);
|
|
129
|
-
expect(manifesto.parseManifest).toHaveBeenCalledWith(mockManifest);
|
|
130
|
-
return [2 /*return*/];
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
}); });
|
|
134
|
-
it("should handle fetch errors", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
135
|
-
return __generator(this, function (_a) {
|
|
136
|
-
switch (_a.label) {
|
|
137
|
-
case 0:
|
|
138
|
-
mockFetch.mockRejectedValueOnce(new Error("Network Error"));
|
|
139
|
-
return [4 /*yield*/, state.fetchManifest("http://example.org/error")];
|
|
140
|
-
case 1:
|
|
141
|
-
_a.sent();
|
|
142
|
-
expect(state.manifests["http://example.org/error"].error).toBe("Network Error");
|
|
143
|
-
expect(state.manifests["http://example.org/error"].isFetching).toBe(false);
|
|
144
|
-
return [2 /*return*/];
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
}); });
|
|
148
|
-
it("should not fetch if already fetched", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
149
|
-
return __generator(this, function (_a) {
|
|
150
|
-
switch (_a.label) {
|
|
151
|
-
case 0:
|
|
152
|
-
// Prime the state
|
|
153
|
-
state.manifests["http://example.org/cached"] = {
|
|
154
|
-
isFetching: false,
|
|
155
|
-
json: {},
|
|
156
|
-
};
|
|
157
|
-
return [4 /*yield*/, state.fetchManifest("http://example.org/cached")];
|
|
158
|
-
case 1:
|
|
159
|
-
_a.sent();
|
|
160
|
-
expect(mockFetch).not.toHaveBeenCalled();
|
|
161
|
-
return [2 /*return*/];
|
|
162
|
-
}
|
|
55
|
+
describe("fetchManifest", () => {
|
|
56
|
+
it("should fetch and store a manifest", async () => {
|
|
57
|
+
const mockManifest = {
|
|
58
|
+
"@id": "http://example.org/manifest",
|
|
59
|
+
label: "Test Manifest",
|
|
60
|
+
};
|
|
61
|
+
mockFetch.mockResolvedValueOnce({
|
|
62
|
+
ok: true,
|
|
63
|
+
json: async () => mockManifest,
|
|
163
64
|
});
|
|
164
|
-
|
|
65
|
+
await state.fetchManifest("http://example.org/manifest");
|
|
66
|
+
expect(mockFetch).toHaveBeenCalledWith("http://example.org/manifest");
|
|
67
|
+
expect(state.manifests["http://example.org/manifest"]).toBeDefined();
|
|
68
|
+
expect(state.manifests["http://example.org/manifest"].json).toEqual(mockManifest);
|
|
69
|
+
expect(state.manifests["http://example.org/manifest"].isFetching).toBe(false);
|
|
70
|
+
expect(manifesto.parseManifest).toHaveBeenCalledWith(mockManifest);
|
|
71
|
+
});
|
|
72
|
+
it("should handle fetch errors", async () => {
|
|
73
|
+
mockFetch.mockRejectedValueOnce(new Error("Network Error"));
|
|
74
|
+
await state.fetchManifest("http://example.org/error");
|
|
75
|
+
expect(state.manifests["http://example.org/error"].error).toBe("Network Error");
|
|
76
|
+
expect(state.manifests["http://example.org/error"].isFetching).toBe(false);
|
|
77
|
+
});
|
|
78
|
+
it("should not fetch if already fetched", async () => {
|
|
79
|
+
// Prime the state
|
|
80
|
+
state.manifests["http://example.org/cached"] = {
|
|
81
|
+
isFetching: false,
|
|
82
|
+
json: {},
|
|
83
|
+
};
|
|
84
|
+
await state.fetchManifest("http://example.org/cached");
|
|
85
|
+
expect(mockFetch).not.toHaveBeenCalled();
|
|
86
|
+
});
|
|
165
87
|
});
|
|
166
|
-
describe("getCanvases",
|
|
167
|
-
it("should return canvases from parsed manifest",
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
});
|
|
184
|
-
}); });
|
|
185
|
-
it("should return empty array if manifest not found", function () {
|
|
186
|
-
var canvases = state.getCanvases("http://example.org/missing");
|
|
88
|
+
describe("getCanvases", () => {
|
|
89
|
+
it("should return canvases from parsed manifest", async () => {
|
|
90
|
+
// Mock internal state directly to avoid fetch overhead
|
|
91
|
+
state.manifests["http://example.org/manifest"] = {
|
|
92
|
+
manifesto: {
|
|
93
|
+
getSequences: () => [
|
|
94
|
+
{
|
|
95
|
+
getCanvases: () => ["mockCanvas1", "mockCanvas2"],
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
const canvases = state.getCanvases("http://example.org/manifest");
|
|
101
|
+
expect(canvases).toEqual(["mockCanvas1", "mockCanvas2"]);
|
|
102
|
+
});
|
|
103
|
+
it("should return empty array if manifest not found", () => {
|
|
104
|
+
const canvases = state.getCanvases("http://example.org/missing");
|
|
187
105
|
expect(canvases).toEqual([]);
|
|
188
106
|
});
|
|
189
107
|
});
|
|
190
|
-
describe("manualGetAnnotations",
|
|
191
|
-
it("should extract annotations and trigger fetch for external lists",
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
// Mock the fetch for the annotation list
|
|
211
|
-
mockFetch.mockResolvedValue({
|
|
212
|
-
ok: true,
|
|
213
|
-
json: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
214
|
-
return [2 /*return*/, ({ resources: [{ "@id": "anno1" }] })];
|
|
215
|
-
}); }); },
|
|
216
|
-
});
|
|
217
|
-
// First call triggers fetch
|
|
218
|
-
// manualGetAnnotations calls fetchAnnotationList which is async, but manualGetAnnotations itself is synchronous and returns partial data
|
|
219
|
-
state.manualGetAnnotations("http://example.org/manifest", "canvas1");
|
|
220
|
-
// We need to wait for the async fetchAnnotationList to complete.
|
|
221
|
-
// Since it's not returned, we can wait a tick or use `vi.waitFor` if available,
|
|
222
|
-
// but simpler here is just to await a small delay since we are mocking.
|
|
223
|
-
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 0); })];
|
|
224
|
-
case 1:
|
|
225
|
-
// We need to wait for the async fetchAnnotationList to complete.
|
|
226
|
-
// Since it's not returned, we can wait a tick or use `vi.waitFor` if available,
|
|
227
|
-
// but simpler here is just to await a small delay since we are mocking.
|
|
228
|
-
_a.sent();
|
|
229
|
-
expect(mockFetch).toHaveBeenCalledWith("http://example.org/list1");
|
|
230
|
-
// Simulate update after fetch (in real app this is reactive, here we manually update state)
|
|
231
|
-
state.manifests["http://example.org/list1"] = {
|
|
232
|
-
json: { resources: [{ "@id": "anno1" }] },
|
|
233
|
-
};
|
|
234
|
-
annos = state.manualGetAnnotations("http://example.org/manifest", "canvas1");
|
|
235
|
-
expect(annos).toHaveLength(1);
|
|
236
|
-
expect(annos[0]["@id"]).toBe("anno1");
|
|
237
|
-
return [2 /*return*/];
|
|
238
|
-
}
|
|
108
|
+
describe("manualGetAnnotations", () => {
|
|
109
|
+
it("should extract annotations and trigger fetch for external lists", async () => {
|
|
110
|
+
// Setup mock state with a manifest that has a canvas
|
|
111
|
+
state.manifests["http://example.org/manifest"] = {
|
|
112
|
+
manifesto: {
|
|
113
|
+
getSequences: () => [
|
|
114
|
+
{
|
|
115
|
+
getCanvasById: () => ({
|
|
116
|
+
__jsonld: {
|
|
117
|
+
otherContent: [{ "@id": "http://example.org/list1" }],
|
|
118
|
+
},
|
|
119
|
+
}),
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
// Mock the fetch for the annotation list
|
|
125
|
+
mockFetch.mockResolvedValue({
|
|
126
|
+
ok: true,
|
|
127
|
+
json: async () => ({ resources: [{ "@id": "anno1" }] }),
|
|
239
128
|
});
|
|
240
|
-
|
|
129
|
+
// First call triggers fetch
|
|
130
|
+
// manualGetAnnotations calls fetchAnnotationList which is async, but manualGetAnnotations itself is synchronous and returns partial data
|
|
131
|
+
state.manualGetAnnotations("http://example.org/manifest", "canvas1");
|
|
132
|
+
// We need to wait for the async fetchAnnotationList to complete.
|
|
133
|
+
// Since it's not returned, we can wait a tick or use `vi.waitFor` if available,
|
|
134
|
+
// but simpler here is just to await a small delay since we are mocking.
|
|
135
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
136
|
+
expect(mockFetch).toHaveBeenCalledWith("http://example.org/list1");
|
|
137
|
+
// Simulate update after fetch (in real app this is reactive, here we manually update state)
|
|
138
|
+
state.manifests["http://example.org/list1"] = {
|
|
139
|
+
json: { resources: [{ "@id": "anno1" }] },
|
|
140
|
+
};
|
|
141
|
+
// Second call should return the annotations
|
|
142
|
+
const annos = state.manualGetAnnotations("http://example.org/manifest", "canvas1");
|
|
143
|
+
expect(annos).toHaveLength(1);
|
|
144
|
+
expect(annos[0]["@id"]).toBe("anno1");
|
|
145
|
+
});
|
|
241
146
|
});
|
|
242
147
|
});
|
|
@@ -43,8 +43,8 @@ export declare class ViewerState {
|
|
|
43
43
|
x: number;
|
|
44
44
|
y: number;
|
|
45
45
|
};
|
|
46
|
-
dragOverSide: "left" | "top" | "bottom" |
|
|
47
|
-
galleryCenterPanelRect: DOMRect;
|
|
46
|
+
dragOverSide: "left" | "right" | "top" | "bottom" | null;
|
|
47
|
+
galleryCenterPanelRect: DOMRect | null;
|
|
48
48
|
/**
|
|
49
49
|
* Event target for dispatching CustomEvents.
|
|
50
50
|
* Only set by TriiiceratopsViewerElement (web component build).
|