graphwise-reactodia 0.0.1-TR7 → 0.0.1-TR9
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/README.md +32 -0
- package/dist/cjs/graphwise-reactodia.cjs.entry.js +309 -41
- package/dist/cjs/index.cjs.js +7 -0
- package/dist/collection/components/graphwise-reactodia/graphwise-reactodia.js +10 -10
- package/dist/collection/components/graphwise-reactodia/models/clear-diagram-storage-event.js +5 -0
- package/dist/collection/components/graphwise-reactodia/models/subscription-list.js +35 -0
- package/dist/collection/components/graphwise-reactodia/models/triple.js +1 -0
- package/dist/collection/components/graphwise-reactodia/providers/service/service-inject.js +15 -0
- package/dist/collection/components/graphwise-reactodia/providers/service/service.js +19 -0
- package/dist/collection/components/graphwise-reactodia/providers/service/service.provider.js +20 -0
- package/dist/collection/components/graphwise-reactodia/reactodia-app.js +61 -28
- package/dist/collection/components/graphwise-reactodia/services/diagram/diagram.service.js +54 -0
- package/dist/collection/components/graphwise-reactodia/services/diagram-storage/diagram-storage.service.js +55 -0
- package/dist/collection/components/graphwise-reactodia/services/event/event.service.js +35 -0
- package/dist/collection/components/graphwise-reactodia/services/window/window.service.js +24 -0
- package/dist/collection/components/graphwise-reactodia/testing/storage.mock.js +35 -0
- package/dist/collection/index.js +1 -1
- package/dist/collection/pages/graphwise-reactodia/main.js +17 -7
- package/dist/esm/graphwise-reactodia.entry.js +306 -38
- package/dist/esm/index.js +6 -0
- package/dist/graphwise-reactodia/graphwise-reactodia.esm.js +1 -1
- package/dist/graphwise-reactodia/index.esm.js +1 -0
- package/dist/graphwise-reactodia/p-5b907998.entry.js +1 -0
- package/dist/types/components/graphwise-reactodia/i18n/translations.d.ts +2 -6
- package/dist/types/components/graphwise-reactodia/models/clear-diagram-storage-event.d.ts +5 -0
- package/dist/types/components/graphwise-reactodia/models/reactodia-app-props.d.ts +6 -7
- package/dist/types/components/graphwise-reactodia/models/reactodia-config.d.ts +8 -6
- package/dist/types/components/graphwise-reactodia/models/subscription-list.d.ts +26 -0
- package/dist/types/components/graphwise-reactodia/models/subscription.d.ts +4 -0
- package/dist/types/components/graphwise-reactodia/models/{reactodia-seed-link.d.ts → triple.d.ts} +2 -6
- package/dist/types/components/graphwise-reactodia/providers/service/service-inject.d.ts +13 -0
- package/dist/types/components/graphwise-reactodia/providers/service/service.d.ts +28 -0
- package/dist/types/components/graphwise-reactodia/providers/service/service.provider.d.ts +16 -0
- package/dist/types/components/graphwise-reactodia/services/diagram/diagram.service.d.ts +26 -0
- package/dist/types/components/graphwise-reactodia/services/diagram-storage/diagram-storage.service.d.ts +26 -0
- package/dist/types/components/graphwise-reactodia/services/event/event.service.d.ts +14 -0
- package/dist/types/components/graphwise-reactodia/services/window/window.service.d.ts +7 -0
- package/dist/types/components/graphwise-reactodia/testing/storage.mock.d.ts +18 -0
- package/dist/types/index.d.ts +1 -1
- package/package.json +9 -3
- package/dist/graphwise-reactodia/p-eb362faa.entry.js +0 -1
- /package/dist/collection/components/graphwise-reactodia/models/{reactodia-seed-link.js → subscription.js} +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider for all {@link Service} instances. Services are singletons: there is only one
|
|
3
|
+
* instance of each service, created on demand and cached here so every consumer shares it.
|
|
4
|
+
*/
|
|
5
|
+
export class ServiceProvider {
|
|
6
|
+
/**
|
|
7
|
+
* Returns the instance of the given service type, creating and caching it on first request.
|
|
8
|
+
*
|
|
9
|
+
* @param type The service type to retrieve.
|
|
10
|
+
* @returns The shared instance of the service.
|
|
11
|
+
* @template T The type of the service to retrieve.
|
|
12
|
+
*/
|
|
13
|
+
static get(type) {
|
|
14
|
+
if (!ServiceProvider.SERVICE_INSTANCES.has(type.ID)) {
|
|
15
|
+
ServiceProvider.SERVICE_INSTANCES.set(type.ID, new type());
|
|
16
|
+
}
|
|
17
|
+
return ServiceProvider.SERVICE_INSTANCES.get(type.ID);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
ServiceProvider.SERVICE_INSTANCES = new Map();
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { createElement } from "react";
|
|
2
2
|
import { createRoot } from "react-dom/client";
|
|
3
|
-
import { DefaultWorkspace, SparqlDataProvider, useLoadedWorkspace, Workspace
|
|
3
|
+
import { DefaultWorkspace, SparqlDataProvider, useLoadedWorkspace, Workspace } from "@reactodia/workspace";
|
|
4
4
|
import { blockingDefaultLayout } from "@reactodia/workspace/layout-sync";
|
|
5
5
|
import { TRANSLATIONS } from "./i18n/translations";
|
|
6
|
+
import { service } from "./providers/service/service-inject";
|
|
7
|
+
import { DiagramService } from "./services/diagram/diagram.service";
|
|
8
|
+
import { DiagramStorageService } from "./services/diagram-storage/diagram-storage.service";
|
|
9
|
+
import { EventService } from "./services/event/event.service";
|
|
10
|
+
import { SubscriptionList } from "./models/subscription-list";
|
|
6
11
|
/**
|
|
7
12
|
* Reactodia ships English as its built-in default bundle, so English needs no override.
|
|
8
13
|
* Other languages are layered on top as partial bundles; unknown codes fall back to English.
|
|
@@ -20,6 +25,12 @@ function translationsForLanguage(language) {
|
|
|
20
25
|
* runs outside React and therefore cannot call the `useWorkspace` hook.
|
|
21
26
|
*/
|
|
22
27
|
let workspaceContext = null;
|
|
28
|
+
/**
|
|
29
|
+
* Active listeners that persist diagram edits to local storage. Populated when the workspace
|
|
30
|
+
* mounts and released in {@link unmountReactodia}, so persistence follows the same lifecycle as
|
|
31
|
+
* the React root.
|
|
32
|
+
*/
|
|
33
|
+
const subscriptions = new SubscriptionList();
|
|
23
34
|
/**
|
|
24
35
|
* Builds a Reactodia {@link SparqlDataProvider} for the given endpoint using the supplied
|
|
25
36
|
* query preset. The host owns the query configuration and passes it in via props; when none
|
|
@@ -30,15 +41,16 @@ function createDataProvider(props) {
|
|
|
30
41
|
return new SparqlDataProvider({
|
|
31
42
|
endpointUrl: currentRepository,
|
|
32
43
|
queryMethod: 'POST',
|
|
33
|
-
queryFunction: config.queryFunction
|
|
44
|
+
queryFunction: config.queryFunction
|
|
34
45
|
}, providerSettings);
|
|
35
46
|
}
|
|
36
47
|
/**
|
|
37
48
|
* Places the seed entities on the canvas. Each IRI is added as a placeholder element, and data is then loaded for the
|
|
38
49
|
* respective nodes using the {@link DataDiagramModel.requestData} method.
|
|
39
50
|
*/
|
|
40
|
-
async function
|
|
51
|
+
async function seedIrisToCanvas(context, dataProvider, seed, signal) {
|
|
41
52
|
const { model, performLayout } = context;
|
|
53
|
+
await model.createNewDiagram({ dataProvider, signal });
|
|
42
54
|
for (const iri of seed) {
|
|
43
55
|
model.createElement(iri);
|
|
44
56
|
}
|
|
@@ -46,18 +58,13 @@ async function seedCanvas(context, seed, signal) {
|
|
|
46
58
|
await performLayout({ signal });
|
|
47
59
|
}
|
|
48
60
|
/**
|
|
49
|
-
* Places a pre-resolved graph (e.g. a CONSTRUCT query result) on the canvas. The
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* their display data is hydrated via {@link DataDiagramModel.requestElementData}.
|
|
53
|
-
*
|
|
54
|
-
* Note we use `requestElementData` rather than `requestData`: the latter would also query the
|
|
55
|
-
* provider for *all* persisted links between the seeded nodes, over-fetching beyond the
|
|
56
|
-
* CONSTRUCT's selection. Hydrating elements alone keeps the canvas to exactly the supplied
|
|
57
|
-
* edges, while further expansion continues lazily against the SPARQL provider.
|
|
61
|
+
* Places a pre-resolved graph (e.g. a CONSTRUCT query result) on the canvas. The difference between this and
|
|
62
|
+
* {@link seedIrisToCanvas} is that this method does not request link data from the SPARQL endpoint, since describe/construct
|
|
63
|
+
* queries are not persisted in the DB. Here we expect provided links and query for element data only
|
|
58
64
|
*/
|
|
59
|
-
async function
|
|
65
|
+
async function seedGraphToCanvas(context, dataProvider, links, signal) {
|
|
60
66
|
const { model, performLayout } = context;
|
|
67
|
+
await model.createNewDiagram({ dataProvider, signal });
|
|
61
68
|
const uniqueIris = new Set();
|
|
62
69
|
links.forEach((link) => {
|
|
63
70
|
var _a;
|
|
@@ -75,11 +82,30 @@ async function seedGraphCanvas(context, links, signal) {
|
|
|
75
82
|
});
|
|
76
83
|
});
|
|
77
84
|
});
|
|
78
|
-
// Request data only for elements.
|
|
79
|
-
// Link data is not available in the DB, since we are displaying construct/describe queries
|
|
80
85
|
await model.requestElementData(Array.from(uniqueIris));
|
|
81
86
|
await performLayout({ signal });
|
|
82
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Subscribes to the model's changes so diagram edits are persisted to local storage. The
|
|
90
|
+
* subscription is tracked in {@link subscriptions} so it is released together with the React
|
|
91
|
+
* root in {@link unmountReactodia}.
|
|
92
|
+
*/
|
|
93
|
+
function onDiagramChange(model) {
|
|
94
|
+
const storage = service(DiagramStorageService);
|
|
95
|
+
const diagramService = service(DiagramService);
|
|
96
|
+
subscriptions.add(diagramService.subscribeToDiagramChange(model, (diagram) => storage.save(diagram)));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Subscribes to the host's "clear persisted diagram" command so the saved layout is dropped on
|
|
100
|
+
* request (e.g. before a fresh seed should take precedence over previously saved edits). The
|
|
101
|
+
* subscription is tracked in {@link subscriptions} so it is released together with the React
|
|
102
|
+
* root in {@link unmountReactodia}.
|
|
103
|
+
*/
|
|
104
|
+
function onClearDiagramStorage() {
|
|
105
|
+
const storage = service(DiagramStorageService);
|
|
106
|
+
const eventService = service(EventService);
|
|
107
|
+
subscriptions.add(eventService.subscribeToClearDiagramStorage(() => storage.clear()));
|
|
108
|
+
}
|
|
83
109
|
/**
|
|
84
110
|
* The Reactodia workspace React component.
|
|
85
111
|
*
|
|
@@ -90,26 +116,32 @@ async function seedGraphCanvas(context, links, signal) {
|
|
|
90
116
|
* provider's lookup. With a seed, the seeded nodes are placed on the canvas on startup.
|
|
91
117
|
*/
|
|
92
118
|
function ReactodiaApp(props) {
|
|
93
|
-
const { language,
|
|
119
|
+
const { language, config } = props;
|
|
120
|
+
const currentDiagram = props.isReload ? exportReactodiaLayout() : undefined;
|
|
94
121
|
const { onMount } = useLoadedWorkspace(async ({ context, signal }) => {
|
|
95
122
|
var _a, _b;
|
|
96
123
|
workspaceContext = context;
|
|
97
124
|
const { model } = context;
|
|
125
|
+
onDiagramChange(model);
|
|
126
|
+
onClearDiagramStorage();
|
|
98
127
|
const dataProvider = createDataProvider(props);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
128
|
+
const isReload = props.isReload;
|
|
129
|
+
const savedDiagram = service(DiagramStorageService).load();
|
|
130
|
+
if (isReload) {
|
|
131
|
+
// Simply reload without using the current state. This may happen when the user switches the language at runtime.
|
|
132
|
+
// since there is no existing mechanism to re-translate the UI at runtime (not for the UI labels at least)
|
|
133
|
+
await model.importLayout({ dataProvider, diagram: currentDiagram, signal });
|
|
134
|
+
}
|
|
135
|
+
else if ((_a = config.seedIris) === null || _a === void 0 ? void 0 : _a.length) {
|
|
136
|
+
await seedIrisToCanvas(context, dataProvider, config.seedIris, signal);
|
|
137
|
+
}
|
|
138
|
+
else if ((_b = config.seedGraph) === null || _b === void 0 ? void 0 : _b.length) {
|
|
139
|
+
await seedGraphToCanvas(context, dataProvider, config.seedGraph, signal);
|
|
104
140
|
}
|
|
105
141
|
else {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
else if ((_b = config.seedIris) === null || _b === void 0 ? void 0 : _b.length) {
|
|
111
|
-
await seedCanvas(context, config.seedIris, signal);
|
|
112
|
-
}
|
|
142
|
+
// Restore the previously saved layout when present, otherwise start empty. Either way this binds the
|
|
143
|
+
// data provider (savedDiagram is undefined -> empty diagram), so the unified search/lookup works.
|
|
144
|
+
await model.importLayout({ dataProvider, diagram: savedDiagram, signal });
|
|
113
145
|
}
|
|
114
146
|
}, [language]);
|
|
115
147
|
/**
|
|
@@ -160,5 +192,6 @@ export function exportReactodiaLayout() {
|
|
|
160
192
|
* Unmounts the Reactodia application.
|
|
161
193
|
*/
|
|
162
194
|
export function unmountReactodia(root) {
|
|
195
|
+
subscriptions.unsubscribeAll();
|
|
163
196
|
root.unmount();
|
|
164
197
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
4
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else
|
|
6
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
7
|
+
if (d = decorators[i])
|
|
8
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
9
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
10
|
+
};
|
|
11
|
+
var DiagramService_1;
|
|
12
|
+
import { Service } from "../../providers/service/service";
|
|
13
|
+
/**
|
|
14
|
+
* Service for diagram related operations and subscriptions
|
|
15
|
+
*/
|
|
16
|
+
let DiagramService = DiagramService_1 = class DiagramService {
|
|
17
|
+
/**
|
|
18
|
+
* Subscribes to diagram changes. On every debounced change the current layout is
|
|
19
|
+
* exported and passed to the callback.
|
|
20
|
+
* Debounce time for the callback trigger is needed, because certain events (like moving a node) can trigger
|
|
21
|
+
* multiple `historyChanged` events in a short time.
|
|
22
|
+
*
|
|
23
|
+
* @param model The diagram model to observe.
|
|
24
|
+
* @param onChangeCallback Called with the exported layout when the diagram changes.
|
|
25
|
+
* @returns A {@link Subscription} that, when called, removes the listener and drops any
|
|
26
|
+
* pending notification.
|
|
27
|
+
*/
|
|
28
|
+
subscribeToDiagramChange(model, onChangeCallback) {
|
|
29
|
+
let notifyTimer;
|
|
30
|
+
const onHistoryChange = () => {
|
|
31
|
+
if (notifyTimer) {
|
|
32
|
+
clearTimeout(notifyTimer);
|
|
33
|
+
}
|
|
34
|
+
notifyTimer = setTimeout(() => {
|
|
35
|
+
notifyTimer = undefined;
|
|
36
|
+
onChangeCallback(model.exportLayout());
|
|
37
|
+
}, DiagramService_1.NOTIFY_DEBOUNCE_MS);
|
|
38
|
+
};
|
|
39
|
+
model.history.events.on(DiagramService_1.HISTORY_CHANGED_EVENT, onHistoryChange);
|
|
40
|
+
return () => {
|
|
41
|
+
model.history.events.off(DiagramService_1.HISTORY_CHANGED_EVENT, onHistoryChange);
|
|
42
|
+
if (notifyTimer) {
|
|
43
|
+
clearTimeout(notifyTimer);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
DiagramService.ID = 'DiagramService';
|
|
49
|
+
DiagramService.NOTIFY_DEBOUNCE_MS = 300;
|
|
50
|
+
DiagramService.HISTORY_CHANGED_EVENT = 'historyChanged';
|
|
51
|
+
DiagramService = DiagramService_1 = __decorate([
|
|
52
|
+
Service
|
|
53
|
+
], DiagramService);
|
|
54
|
+
export { DiagramService };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
4
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else
|
|
6
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
7
|
+
if (d = decorators[i])
|
|
8
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
9
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
10
|
+
};
|
|
11
|
+
var DiagramStorageService_1;
|
|
12
|
+
import { Service } from "../../providers/service/service";
|
|
13
|
+
import { service } from "../../providers/service/service-inject";
|
|
14
|
+
import { WindowService } from "../window/window.service";
|
|
15
|
+
/**
|
|
16
|
+
* Service for local store-related diagram operations
|
|
17
|
+
*/
|
|
18
|
+
let DiagramStorageService = DiagramStorageService_1 = class DiagramStorageService {
|
|
19
|
+
/**
|
|
20
|
+
* Load the persisted diagram from the local store, or `undefined` when nothing is stored (or the stored value
|
|
21
|
+
* is unreadable).
|
|
22
|
+
*/
|
|
23
|
+
load() {
|
|
24
|
+
const raw = this.storage.getItem(DiagramStorageService_1.STORAGE_KEY);
|
|
25
|
+
if (!raw) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return JSON.parse(raw);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Persists the given diagram serialization.
|
|
32
|
+
*/
|
|
33
|
+
save(diagram) {
|
|
34
|
+
this.storage.setItem(DiagramStorageService_1.STORAGE_KEY, JSON.stringify(diagram));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Removes the persisted diagram. Used when a new view (a seed) should take precedence over
|
|
38
|
+
* previously saved edits.
|
|
39
|
+
*/
|
|
40
|
+
clear() {
|
|
41
|
+
this.storage.removeItem(DiagramStorageService_1.STORAGE_KEY);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Local storage getter
|
|
45
|
+
*/
|
|
46
|
+
get storage() {
|
|
47
|
+
return service(WindowService).getWindow().localStorage;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
DiagramStorageService.ID = 'DiagramStorageService';
|
|
51
|
+
DiagramStorageService.STORAGE_KEY = 'diagram.state';
|
|
52
|
+
DiagramStorageService = DiagramStorageService_1 = __decorate([
|
|
53
|
+
Service
|
|
54
|
+
], DiagramStorageService);
|
|
55
|
+
export { DiagramStorageService };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
4
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else
|
|
6
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
7
|
+
if (d = decorators[i])
|
|
8
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
9
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
10
|
+
};
|
|
11
|
+
import { Service } from "../../providers/service/service";
|
|
12
|
+
import { CLEAR_DIAGRAM_STORAGE_EVENT } from "../../models/clear-diagram-storage-event";
|
|
13
|
+
import { service } from "../../providers/service/service-inject";
|
|
14
|
+
import { WindowService } from "../window/window.service";
|
|
15
|
+
/**
|
|
16
|
+
* Service for event based operations
|
|
17
|
+
*/
|
|
18
|
+
let EventService = class EventService {
|
|
19
|
+
/**
|
|
20
|
+
* Subscribes to the host's "clear persisted diagram" command.
|
|
21
|
+
*
|
|
22
|
+
* @param onClear Called whenever the event fires.
|
|
23
|
+
* @returns A {@link Subscription} that, when called, removes the listener.
|
|
24
|
+
*/
|
|
25
|
+
subscribeToClearDiagramStorage(onClear) {
|
|
26
|
+
const target = service(WindowService).getWindow();
|
|
27
|
+
target.addEventListener(CLEAR_DIAGRAM_STORAGE_EVENT, onClear);
|
|
28
|
+
return () => target.removeEventListener(CLEAR_DIAGRAM_STORAGE_EVENT, onClear);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
EventService.ID = 'EventService';
|
|
32
|
+
EventService = __decorate([
|
|
33
|
+
Service
|
|
34
|
+
], EventService);
|
|
35
|
+
export { EventService };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
4
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else
|
|
6
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
7
|
+
if (d = decorators[i])
|
|
8
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
9
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
10
|
+
};
|
|
11
|
+
import { Service } from "../../providers/service/service";
|
|
12
|
+
/**
|
|
13
|
+
* Service that provides access to browser window-related functionality.
|
|
14
|
+
*/
|
|
15
|
+
let WindowService = class WindowService {
|
|
16
|
+
getWindow() {
|
|
17
|
+
return window;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
WindowService.ID = 'WindowService';
|
|
21
|
+
WindowService = __decorate([
|
|
22
|
+
Service
|
|
23
|
+
], WindowService);
|
|
24
|
+
export { WindowService };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal in-memory {@link Storage}, so services that read `localStorage` can be exercised
|
|
3
|
+
* without a real browser store and asserted against directly. Shared across test suites.
|
|
4
|
+
*/
|
|
5
|
+
export class StorageMock {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.store = new Map();
|
|
8
|
+
}
|
|
9
|
+
get length() {
|
|
10
|
+
return this.store.size;
|
|
11
|
+
}
|
|
12
|
+
clear() {
|
|
13
|
+
this.store.clear();
|
|
14
|
+
}
|
|
15
|
+
getItem(key) {
|
|
16
|
+
return this.store.has(key) ? this.store.get(key) : null;
|
|
17
|
+
}
|
|
18
|
+
key(index) {
|
|
19
|
+
var _a;
|
|
20
|
+
return (_a = Array.from(this.store.keys())[index]) !== null && _a !== void 0 ? _a : null;
|
|
21
|
+
}
|
|
22
|
+
removeItem(key) {
|
|
23
|
+
this.store.delete(key);
|
|
24
|
+
}
|
|
25
|
+
setItem(key, value) {
|
|
26
|
+
this.store.set(key, value);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates a fresh {@link StorageMock}. Suites install the returned instance as the global
|
|
31
|
+
* `localStorage` themselves.
|
|
32
|
+
*/
|
|
33
|
+
export function createStorageMock() {
|
|
34
|
+
return new StorageMock();
|
|
35
|
+
}
|
package/dist/collection/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export { CLEAR_DIAGRAM_STORAGE_EVENT } from './components/graphwise-reactodia/models/clear-diagram-storage-event';
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// There is no SPARQL endpoint behind the dev server, so every query is answered with an empty
|
|
2
|
+
// result. The shape has to match what the provider asks for: SELECT/ASK queries are parsed with
|
|
3
|
+
// `response.json()` and would blow up on an empty body, CONSTRUCT/DESCRIBE queries are parsed as
|
|
4
|
+
// turtle, where an empty body is a valid (empty) graph.
|
|
5
|
+
async function stubQueryFunction(params) {
|
|
6
|
+
const accept = params.headers?.['Accept'] ?? '';
|
|
7
|
+
if (accept.includes('sparql-results+json')) {
|
|
8
|
+
const body = JSON.stringify({head: {vars: []}, results: {bindings: []}, boolean: false});
|
|
9
|
+
return new Response(body, {headers: {'Content-Type': 'application/sparql-results+json'}});
|
|
10
|
+
}
|
|
11
|
+
return new Response('', {headers: {'Content-Type': 'text/turtle'}});
|
|
4
12
|
}
|
|
5
13
|
|
|
6
|
-
// IRIs of the entities the host asks to pre-populate the canvas with on startup.
|
|
7
14
|
const SEED_NODES = ['http://example.com/alice', 'http://example.com/bob'];
|
|
8
15
|
|
|
9
|
-
// Pre-resolved edges (e.g. a CONSTRUCT result) the host asks to draw directly on the canvas,
|
|
10
|
-
// without querying the SPARQL endpoint for link data.
|
|
11
16
|
const SEED_GRAPH = [
|
|
12
17
|
{
|
|
13
18
|
source: 'http://example.com/alice',
|
|
14
19
|
target: 'http://example.com/bob',
|
|
15
|
-
predicates: ['knows'],
|
|
16
20
|
rawPredicates: ['http://example.com/knows'],
|
|
17
21
|
},
|
|
18
22
|
];
|
|
@@ -38,3 +42,9 @@ function setRepository(repository) {
|
|
|
38
42
|
function setLanguage(language) {
|
|
39
43
|
reactodia.language = language;
|
|
40
44
|
}
|
|
45
|
+
|
|
46
|
+
// The host asks the component to drop its persisted diagram by dispatching a namespaced window
|
|
47
|
+
// event, rather than holding an element reference and calling a method on it.
|
|
48
|
+
function clearDiagramStorage() {
|
|
49
|
+
window.dispatchEvent(new Event('graphwise-reactodia:clear-diagram-storage'));
|
|
50
|
+
}
|