@kispace-io/gs-lib 0.0.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/README.md +58 -0
- package/bin/map-builder.js +132 -0
- package/dist/base-map-builder.d.ts +102 -0
- package/dist/base-map-builder.d.ts.map +1 -0
- package/dist/gs-gs2ol.d.ts +41 -0
- package/dist/gs-gs2ol.d.ts.map +1 -0
- package/dist/gs-lib.css +3724 -0
- package/dist/gs-lib.d.ts +16 -0
- package/dist/gs-lib.d.ts.map +1 -0
- package/dist/gs-litns.d.ts +32 -0
- package/dist/gs-litns.d.ts.map +1 -0
- package/dist/gs-model.d.ts +186 -0
- package/dist/gs-model.d.ts.map +1 -0
- package/dist/gs-ol-adapters.d.ts +23 -0
- package/dist/gs-ol-adapters.d.ts.map +1 -0
- package/dist/gs-ol2gs.d.ts +9 -0
- package/dist/gs-ol2gs.d.ts.map +1 -0
- package/dist/gs-olns.d.ts +22 -0
- package/dist/gs-olns.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.html +69 -0
- package/dist/index.js +104888 -0
- package/dist/index.js.map +1 -0
- package/dist/pwa/assets/icons/192x192.png +0 -0
- package/dist/pwa/assets/icons/24x24.png +0 -0
- package/dist/pwa/assets/icons/48x48.png +0 -0
- package/dist/pwa/assets/icons/512x512.png +0 -0
- package/dist/pwa/assets/icons/icon_192.png +0 -0
- package/dist/pwa/assets/icons/icon_24.png +0 -0
- package/dist/pwa/assets/icons/icon_48.png +0 -0
- package/dist/pwa/assets/icons/icon_512.png +0 -0
- package/dist/pwa/manifest.json +54 -0
- package/dist/pwa/staticwebapp.config.json +6 -0
- package/dist/pwa/sw.js +109 -0
- package/lib/node-map-builder.ts +200 -0
- package/package.json +51 -0
- package/public/index.html +69 -0
- package/public/pwa/assets/icons/192x192.png +0 -0
- package/public/pwa/assets/icons/24x24.png +0 -0
- package/public/pwa/assets/icons/48x48.png +0 -0
- package/public/pwa/assets/icons/512x512.png +0 -0
- package/public/pwa/assets/icons/icon_192.png +0 -0
- package/public/pwa/assets/icons/icon_24.png +0 -0
- package/public/pwa/assets/icons/icon_48.png +0 -0
- package/public/pwa/assets/icons/icon_512.png +0 -0
- package/public/pwa/manifest.json +54 -0
- package/public/pwa/staticwebapp.config.json +6 -0
- package/public/pwa/sw.js +109 -0
- package/src/base-map-builder.ts +414 -0
- package/src/gs-gs2ol.ts +626 -0
- package/src/gs-lib.ts +54 -0
- package/src/gs-litns.ts +213 -0
- package/src/gs-model.ts +393 -0
- package/src/gs-ol-adapters.ts +89 -0
- package/src/gs-ol2gs.ts +86 -0
- package/src/gs-olns.ts +30 -0
- package/src/index.ts +15 -0
- package/tsconfig.json +23 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "/",
|
|
3
|
+
"scope": "/",
|
|
4
|
+
"name": "$PWA_NAME",
|
|
5
|
+
"display": "standalone",
|
|
6
|
+
"start_url": "/",
|
|
7
|
+
"short_name": "$PWA_SHORT_NAME",
|
|
8
|
+
"description": "$PWA_DESCRIPTION",
|
|
9
|
+
"version": "$PWA_VERSION",
|
|
10
|
+
"orientation": "any",
|
|
11
|
+
"related_applications": [],
|
|
12
|
+
"prefer_related_applications": false,
|
|
13
|
+
"display_override": [
|
|
14
|
+
"window-controls-overlay"
|
|
15
|
+
],
|
|
16
|
+
"launch_handler": {
|
|
17
|
+
"client_mode": "focus-existing"
|
|
18
|
+
},
|
|
19
|
+
"icons": [
|
|
20
|
+
{
|
|
21
|
+
"src": "assets/icons/512x512.png",
|
|
22
|
+
"sizes": "512x512",
|
|
23
|
+
"type": "image/png"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"src": "assets/icons/192x192.png",
|
|
27
|
+
"sizes": "192x192",
|
|
28
|
+
"type": "image/png"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"src": "assets/icons/48x48.png",
|
|
32
|
+
"sizes": "48x48",
|
|
33
|
+
"type": "image/png"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"src": "assets/icons/24x24.png",
|
|
37
|
+
"sizes": "24x24",
|
|
38
|
+
"type": "image/png"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"screenshots": [],
|
|
42
|
+
"features": [
|
|
43
|
+
"Cross Platform",
|
|
44
|
+
"fast",
|
|
45
|
+
"interactive"
|
|
46
|
+
],
|
|
47
|
+
"categories": [
|
|
48
|
+
"mapping",
|
|
49
|
+
"geospatial",
|
|
50
|
+
"interaction"
|
|
51
|
+
],
|
|
52
|
+
"shortcuts": [],
|
|
53
|
+
"widgets": []
|
|
54
|
+
}
|
package/dist/pwa/sw.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
importScripts(
|
|
2
|
+
'https://storage.googleapis.com/workbox-cdn/releases/7.3.0/workbox-sw.js'
|
|
3
|
+
);
|
|
4
|
+
|
|
5
|
+
// Version management for PWA updates
|
|
6
|
+
const CACHE_VERSION = '$PWA_VERSION';
|
|
7
|
+
const CACHE_NAME = `geospace-v${CACHE_VERSION}`;
|
|
8
|
+
|
|
9
|
+
// This is your Service Worker, you can put any of your custom Service Worker
|
|
10
|
+
// code in this file, above the `precacheAndRoute` line.
|
|
11
|
+
|
|
12
|
+
// When widget is installed/pinned, push initial state.
|
|
13
|
+
self.addEventListener('widgetinstall', (event) => {
|
|
14
|
+
event.waitUntil(updateWidget(event));
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// When widget is shown, update content to ensure it is up-to-date.
|
|
18
|
+
self.addEventListener('widgetresume', (event) => {
|
|
19
|
+
event.waitUntil(updateWidget(event));
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// When the user clicks an element with an associated Action.Execute,
|
|
23
|
+
// handle according to the 'verb' in event.action.
|
|
24
|
+
self.addEventListener('widgetclick', (event) => {
|
|
25
|
+
if (event.action == "updateName") {
|
|
26
|
+
event.waitUntil(updateName(event));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// When the widget is uninstalled/unpinned, clean up any unnecessary
|
|
31
|
+
// periodic sync or widget-related state.
|
|
32
|
+
self.addEventListener('widgetuninstall', (event) => {});
|
|
33
|
+
|
|
34
|
+
// Handle service worker updates and version changes
|
|
35
|
+
self.addEventListener('install', (event) => {
|
|
36
|
+
console.log(`Service Worker installing version ${CACHE_VERSION}`);
|
|
37
|
+
// Skip waiting to activate immediately
|
|
38
|
+
self.skipWaiting();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
self.addEventListener('activate', (event) => {
|
|
42
|
+
console.log(`Service Worker activating version ${CACHE_VERSION}`);
|
|
43
|
+
event.waitUntil(
|
|
44
|
+
// Clean up old caches
|
|
45
|
+
caches.keys().then((cacheNames) => {
|
|
46
|
+
return Promise.all(
|
|
47
|
+
cacheNames.map((cacheName) => {
|
|
48
|
+
// Delete caches that don't match current version
|
|
49
|
+
if (cacheName.startsWith('geospace-v') && cacheName !== CACHE_NAME) {
|
|
50
|
+
console.log(`Deleting old cache: ${cacheName}`);
|
|
51
|
+
return caches.delete(cacheName);
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
}).then(() => {
|
|
56
|
+
// Take control of all clients immediately
|
|
57
|
+
return self.clients.claim().then(() => {
|
|
58
|
+
// Notify all clients about the new version
|
|
59
|
+
return self.clients.matchAll().then(clients => {
|
|
60
|
+
clients.forEach(client => {
|
|
61
|
+
client.postMessage({
|
|
62
|
+
type: 'RELOAD',
|
|
63
|
+
version: CACHE_VERSION
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
})
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Handle version change notifications
|
|
73
|
+
self.addEventListener('message', (event) => {
|
|
74
|
+
if (event.data && event.data.type === 'SKIP_WAITING') {
|
|
75
|
+
self.skipWaiting();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const updateWidget = async (event) => {
|
|
80
|
+
// The widget definition represents the fields specified in the manifest.
|
|
81
|
+
const widgetDefinition = event.widget.definition;
|
|
82
|
+
|
|
83
|
+
// Fetch the template and data defined in the manifest to generate the payload.
|
|
84
|
+
const payload = {
|
|
85
|
+
template: JSON.stringify(await (await fetch(widgetDefinition.msAcTemplate)).json()),
|
|
86
|
+
data: JSON.stringify(await (await fetch(widgetDefinition.data)).json()),
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Push payload to widget.
|
|
90
|
+
await self.widgets.updateByInstanceId(event.instanceId, payload);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const updateName = async (event) => {
|
|
94
|
+
const name = event.data.json().name;
|
|
95
|
+
|
|
96
|
+
// The widget definition represents the fields specified in the manifest.
|
|
97
|
+
const widgetDefinition = event.widget.definition;
|
|
98
|
+
|
|
99
|
+
// Fetch the template and data defined in the manifest to generate the payload.
|
|
100
|
+
const payload = {
|
|
101
|
+
template: JSON.stringify(await (await fetch(widgetDefinition.msAcTemplate)).json()),
|
|
102
|
+
data: JSON.stringify({name}),
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// Push payload to widget.
|
|
106
|
+
await self.widgets.updateByInstanceId(event.instanceId, payload);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
workbox.precaching.precacheAndRoute(self.__WB_MANIFEST || []);
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
// Dynamic imports for Node.js modules to avoid bundling in browser builds
|
|
2
|
+
import {
|
|
3
|
+
BuildOptions,
|
|
4
|
+
FileSystem,
|
|
5
|
+
ProgressCallback,
|
|
6
|
+
buildMap,
|
|
7
|
+
calculateTotalSteps,
|
|
8
|
+
createCopyAssetsFunction
|
|
9
|
+
} from '../src/base-map-builder'
|
|
10
|
+
import {GsMap} from '../src/gs-model'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create a Node.js file system implementation
|
|
14
|
+
*/
|
|
15
|
+
export async function createNodeFileSystem(projectRoot: string): Promise<FileSystem> {
|
|
16
|
+
// Dynamic imports to avoid bundling Node.js modules in browser builds
|
|
17
|
+
const path = await import('path')
|
|
18
|
+
const fs = await import('fs/promises')
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
async readFile(filePath: string): Promise<string | Uint8Array> {
|
|
22
|
+
const fullPath = path.resolve(projectRoot, filePath)
|
|
23
|
+
return await fs.readFile(fullPath)
|
|
24
|
+
},
|
|
25
|
+
async writeFile(filePath: string, content: string | Uint8Array): Promise<void> {
|
|
26
|
+
const fullPath = path.resolve(projectRoot, filePath)
|
|
27
|
+
await fs.mkdir(path.dirname(fullPath), { recursive: true })
|
|
28
|
+
await fs.writeFile(fullPath, content)
|
|
29
|
+
},
|
|
30
|
+
async ensureDir(dirPath: string): Promise<void> {
|
|
31
|
+
const fullPath = path.resolve(projectRoot, dirPath)
|
|
32
|
+
await fs.mkdir(fullPath, { recursive: true })
|
|
33
|
+
},
|
|
34
|
+
async exists(filePath: string): Promise<boolean> {
|
|
35
|
+
const fullPath = path.resolve(projectRoot, filePath)
|
|
36
|
+
try {
|
|
37
|
+
await fs.access(fullPath)
|
|
38
|
+
return true
|
|
39
|
+
} catch {
|
|
40
|
+
return false
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
async deleteDir(dirPath: string): Promise<void> {
|
|
44
|
+
const fullPath = path.resolve(projectRoot, dirPath)
|
|
45
|
+
await fs.rm(fullPath, { recursive: true, force: true })
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Create an esbuild plugin that resolves modules from a Node.js file system
|
|
52
|
+
*/
|
|
53
|
+
export async function createNodeResolvePlugin(projectRoot: string, gsLibPath: string): Promise<any> {
|
|
54
|
+
// Dynamic imports to avoid bundling Node.js modules in browser builds
|
|
55
|
+
const path = await import('path')
|
|
56
|
+
const fs = await import('fs/promises')
|
|
57
|
+
const esbuild = await import('esbuild')
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
name: 'node-resolve',
|
|
61
|
+
setup(build: any) {
|
|
62
|
+
build.onResolve({ filter: /.*/ }, (args: any) => {
|
|
63
|
+
// Skip external URLs
|
|
64
|
+
if (args.path.startsWith('http://') || args.path.startsWith('https://')) {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let resolvedPath = args.path
|
|
69
|
+
|
|
70
|
+
// Resolve @kispace-io/gs-lib to the provided path
|
|
71
|
+
if (args.path === '@kispace-io/gs-lib') {
|
|
72
|
+
return { path: path.resolve(projectRoot, gsLibPath), namespace: 'file' }
|
|
73
|
+
}
|
|
74
|
+
if (args.path.startsWith('@kispace-io/gs-lib/')) {
|
|
75
|
+
const subpath = args.path.replace('@kispace-io/gs-lib/', '')
|
|
76
|
+
return { path: path.resolve(projectRoot, gsLibPath.replace('index.js', subpath)), namespace: 'file' }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Handle relative paths
|
|
80
|
+
if (args.path.startsWith('./') || args.path.startsWith('../')) {
|
|
81
|
+
if (args.importer) {
|
|
82
|
+
const importerDir = path.dirname(args.importer)
|
|
83
|
+
resolvedPath = path.resolve(importerDir, args.path)
|
|
84
|
+
} else {
|
|
85
|
+
resolvedPath = path.resolve(projectRoot, args.path)
|
|
86
|
+
}
|
|
87
|
+
} else if (!path.isAbsolute(args.path)) {
|
|
88
|
+
// Bare specifier - resolve relative to project root
|
|
89
|
+
resolvedPath = path.resolve(projectRoot, args.path)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return { path: resolvedPath, namespace: 'file' }
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
build.onLoad({ filter: /.*/, namespace: 'file' }, async (args: any) => {
|
|
96
|
+
try {
|
|
97
|
+
const contents = await fs.readFile(args.path, 'utf-8')
|
|
98
|
+
const ext = path.extname(args.path)
|
|
99
|
+
const loader = ext === '.ts' ? 'ts' : ext === '.js' ? 'js' : ext === '.json' ? 'json' : 'js'
|
|
100
|
+
return { contents, loader }
|
|
101
|
+
} catch (error: any) {
|
|
102
|
+
throw new Error(`Failed to load ${args.path}: ${error.message}`)
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Build a complete .geospace project for CI/CD
|
|
112
|
+
* This function can be used in Node.js without geospace or appspace packages
|
|
113
|
+
*
|
|
114
|
+
* @param projectRoot - Root directory of the .geospace project
|
|
115
|
+
* @param mapFile - Path to the .geospace map file (relative to projectRoot)
|
|
116
|
+
* @param options - Build configuration options
|
|
117
|
+
* @param progress - Optional progress callback
|
|
118
|
+
*/
|
|
119
|
+
export async function buildProject(
|
|
120
|
+
projectRoot: string,
|
|
121
|
+
mapFile: string,
|
|
122
|
+
options: {
|
|
123
|
+
title?: string,
|
|
124
|
+
version?: string,
|
|
125
|
+
env?: Record<string, string>,
|
|
126
|
+
gsLibPackagePath?: string,
|
|
127
|
+
outputDir?: string,
|
|
128
|
+
cleanAfterBuild?: boolean
|
|
129
|
+
} = {},
|
|
130
|
+
progress?: ProgressCallback
|
|
131
|
+
): Promise<void> {
|
|
132
|
+
const {
|
|
133
|
+
title,
|
|
134
|
+
version,
|
|
135
|
+
env,
|
|
136
|
+
gsLibPackagePath,
|
|
137
|
+
outputDir,
|
|
138
|
+
cleanAfterBuild
|
|
139
|
+
} = options
|
|
140
|
+
|
|
141
|
+
if (!version) {
|
|
142
|
+
throw new Error('version is required')
|
|
143
|
+
}
|
|
144
|
+
if (!env) {
|
|
145
|
+
throw new Error('env is required')
|
|
146
|
+
}
|
|
147
|
+
if (!gsLibPackagePath) {
|
|
148
|
+
throw new Error('gsLibPackagePath is required')
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Dynamic imports to avoid bundling Node.js modules in browser builds
|
|
152
|
+
const path = await import('path')
|
|
153
|
+
const nodeFs = await import('fs/promises')
|
|
154
|
+
|
|
155
|
+
const fs = await createNodeFileSystem(projectRoot)
|
|
156
|
+
const gsLibDistPath = path.join(gsLibPackagePath, 'dist')
|
|
157
|
+
const gsLibPublicPath = path.join(gsLibPackagePath, 'public')
|
|
158
|
+
const buildGsLibPath = '__build/gs-lib/index.js'
|
|
159
|
+
|
|
160
|
+
// Calculate total steps early
|
|
161
|
+
const hasAssets = await fs.exists('assets')
|
|
162
|
+
const totalSteps = calculateTotalSteps(true, hasAssets, true, cleanAfterBuild ?? true)
|
|
163
|
+
|
|
164
|
+
// Read map file
|
|
165
|
+
let step = 0
|
|
166
|
+
if (progress) progress(++step, "Reading map file...", totalSteps)
|
|
167
|
+
const mapContent = Buffer.from(await fs.readFile(mapFile)).toString('utf-8')
|
|
168
|
+
const gsMap: GsMap = JSON.parse(mapContent)
|
|
169
|
+
|
|
170
|
+
const buildTitle = title || path.basename(mapFile, '.geospace')
|
|
171
|
+
|
|
172
|
+
// Use standard copyAssets function
|
|
173
|
+
const copyAssets = createCopyAssetsFunction(fs)
|
|
174
|
+
|
|
175
|
+
// Build using unified function
|
|
176
|
+
// Dynamic import to avoid bundling esbuild in browser builds
|
|
177
|
+
const esbuild = await import('esbuild')
|
|
178
|
+
|
|
179
|
+
await buildMap(
|
|
180
|
+
{
|
|
181
|
+
title: buildTitle,
|
|
182
|
+
gsMap,
|
|
183
|
+
env,
|
|
184
|
+
version
|
|
185
|
+
},
|
|
186
|
+
fs,
|
|
187
|
+
await createNodeResolvePlugin(projectRoot, buildGsLibPath),
|
|
188
|
+
esbuild, // Pass Node.js esbuild instance
|
|
189
|
+
{
|
|
190
|
+
outputDir,
|
|
191
|
+
gsLibPackagePath,
|
|
192
|
+
cleanAfterBuild,
|
|
193
|
+
copyAssets,
|
|
194
|
+
startingStep: step,
|
|
195
|
+
totalSteps
|
|
196
|
+
} as any,
|
|
197
|
+
progress
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kispace-io/gs-lib",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "EPL-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/erdalkaraca/geospace.git"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"bin": {
|
|
13
|
+
"map-builder": "./bin/map-builder.js"
|
|
14
|
+
},
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"src",
|
|
24
|
+
"lib",
|
|
25
|
+
"public",
|
|
26
|
+
"bin",
|
|
27
|
+
"tsconfig.json",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "vite build",
|
|
32
|
+
"type-check": "tsc --noEmit"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"ol": "^10.6.1",
|
|
36
|
+
"ol-mapbox-style": "^13.1.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@kispace-io/appspace": "*"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^24.9.2",
|
|
46
|
+
"@types/uuid": "^10.0.0",
|
|
47
|
+
"typescript": "~5.9.3",
|
|
48
|
+
"vite": "^7.1.12",
|
|
49
|
+
"vite-plugin-dts": "^4.5.4"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" translate="no">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8"/>
|
|
5
|
+
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
6
|
+
<meta name="google" content="notranslate">
|
|
7
|
+
|
|
8
|
+
<meta name="mobile-web-app-capable" content="yes">
|
|
9
|
+
<meta name="apple-mobile-web-app-title" content="geospace-app" />
|
|
10
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
|
11
|
+
|
|
12
|
+
<link rel="icon" href="/assets/icons/icon_24.png" type="image/png" />
|
|
13
|
+
<link rel="manifest" href="manifest.json" />
|
|
14
|
+
|
|
15
|
+
<title>$TITLE</title>
|
|
16
|
+
<link rel="stylesheet" href="app.css" />
|
|
17
|
+
<style>
|
|
18
|
+
html, body, .map-container {
|
|
19
|
+
height: 100dvh;
|
|
20
|
+
width: 100dvw;
|
|
21
|
+
margin: 0;
|
|
22
|
+
padding: 0;
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.no-touch {
|
|
27
|
+
touch-action: none;
|
|
28
|
+
}
|
|
29
|
+
</style>
|
|
30
|
+
</head>
|
|
31
|
+
<body>
|
|
32
|
+
<div class="map-container"></div>
|
|
33
|
+
<script type="module">
|
|
34
|
+
import {renderMap} from "./app.js"
|
|
35
|
+
renderMap("div.map-container")
|
|
36
|
+
</script>
|
|
37
|
+
<script>
|
|
38
|
+
if ('serviceWorker' in navigator) {
|
|
39
|
+
window.onload = () => {
|
|
40
|
+
navigator.serviceWorker.register('/sw.js').then(registration => {
|
|
41
|
+
// Check for updates
|
|
42
|
+
registration.addEventListener('updatefound', () => {
|
|
43
|
+
const newWorker = registration.installing;
|
|
44
|
+
if (newWorker) {
|
|
45
|
+
newWorker.addEventListener('statechange', () => {
|
|
46
|
+
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
|
47
|
+
// New version available
|
|
48
|
+
if (confirm('A new version of the app is available. Reload to update?')) {
|
|
49
|
+
newWorker.postMessage({ type: 'SKIP_WAITING' });
|
|
50
|
+
window.location.reload();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Listen for service worker messages
|
|
58
|
+
navigator.serviceWorker.addEventListener('message', event => {
|
|
59
|
+
if (event.data && event.data.type === 'RELOAD') {
|
|
60
|
+
window.location.reload();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
</script>
|
|
67
|
+
</body>
|
|
68
|
+
</html>
|
|
69
|
+
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "/",
|
|
3
|
+
"scope": "/",
|
|
4
|
+
"name": "$PWA_NAME",
|
|
5
|
+
"display": "standalone",
|
|
6
|
+
"start_url": "/",
|
|
7
|
+
"short_name": "$PWA_SHORT_NAME",
|
|
8
|
+
"description": "$PWA_DESCRIPTION",
|
|
9
|
+
"version": "$PWA_VERSION",
|
|
10
|
+
"orientation": "any",
|
|
11
|
+
"related_applications": [],
|
|
12
|
+
"prefer_related_applications": false,
|
|
13
|
+
"display_override": [
|
|
14
|
+
"window-controls-overlay"
|
|
15
|
+
],
|
|
16
|
+
"launch_handler": {
|
|
17
|
+
"client_mode": "focus-existing"
|
|
18
|
+
},
|
|
19
|
+
"icons": [
|
|
20
|
+
{
|
|
21
|
+
"src": "assets/icons/512x512.png",
|
|
22
|
+
"sizes": "512x512",
|
|
23
|
+
"type": "image/png"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"src": "assets/icons/192x192.png",
|
|
27
|
+
"sizes": "192x192",
|
|
28
|
+
"type": "image/png"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"src": "assets/icons/48x48.png",
|
|
32
|
+
"sizes": "48x48",
|
|
33
|
+
"type": "image/png"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"src": "assets/icons/24x24.png",
|
|
37
|
+
"sizes": "24x24",
|
|
38
|
+
"type": "image/png"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"screenshots": [],
|
|
42
|
+
"features": [
|
|
43
|
+
"Cross Platform",
|
|
44
|
+
"fast",
|
|
45
|
+
"interactive"
|
|
46
|
+
],
|
|
47
|
+
"categories": [
|
|
48
|
+
"mapping",
|
|
49
|
+
"geospatial",
|
|
50
|
+
"interaction"
|
|
51
|
+
],
|
|
52
|
+
"shortcuts": [],
|
|
53
|
+
"widgets": []
|
|
54
|
+
}
|