@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.
Files changed (59) hide show
  1. package/README.md +58 -0
  2. package/bin/map-builder.js +132 -0
  3. package/dist/base-map-builder.d.ts +102 -0
  4. package/dist/base-map-builder.d.ts.map +1 -0
  5. package/dist/gs-gs2ol.d.ts +41 -0
  6. package/dist/gs-gs2ol.d.ts.map +1 -0
  7. package/dist/gs-lib.css +3724 -0
  8. package/dist/gs-lib.d.ts +16 -0
  9. package/dist/gs-lib.d.ts.map +1 -0
  10. package/dist/gs-litns.d.ts +32 -0
  11. package/dist/gs-litns.d.ts.map +1 -0
  12. package/dist/gs-model.d.ts +186 -0
  13. package/dist/gs-model.d.ts.map +1 -0
  14. package/dist/gs-ol-adapters.d.ts +23 -0
  15. package/dist/gs-ol-adapters.d.ts.map +1 -0
  16. package/dist/gs-ol2gs.d.ts +9 -0
  17. package/dist/gs-ol2gs.d.ts.map +1 -0
  18. package/dist/gs-olns.d.ts +22 -0
  19. package/dist/gs-olns.d.ts.map +1 -0
  20. package/dist/index.d.ts +11 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.html +69 -0
  23. package/dist/index.js +104888 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/pwa/assets/icons/192x192.png +0 -0
  26. package/dist/pwa/assets/icons/24x24.png +0 -0
  27. package/dist/pwa/assets/icons/48x48.png +0 -0
  28. package/dist/pwa/assets/icons/512x512.png +0 -0
  29. package/dist/pwa/assets/icons/icon_192.png +0 -0
  30. package/dist/pwa/assets/icons/icon_24.png +0 -0
  31. package/dist/pwa/assets/icons/icon_48.png +0 -0
  32. package/dist/pwa/assets/icons/icon_512.png +0 -0
  33. package/dist/pwa/manifest.json +54 -0
  34. package/dist/pwa/staticwebapp.config.json +6 -0
  35. package/dist/pwa/sw.js +109 -0
  36. package/lib/node-map-builder.ts +200 -0
  37. package/package.json +51 -0
  38. package/public/index.html +69 -0
  39. package/public/pwa/assets/icons/192x192.png +0 -0
  40. package/public/pwa/assets/icons/24x24.png +0 -0
  41. package/public/pwa/assets/icons/48x48.png +0 -0
  42. package/public/pwa/assets/icons/512x512.png +0 -0
  43. package/public/pwa/assets/icons/icon_192.png +0 -0
  44. package/public/pwa/assets/icons/icon_24.png +0 -0
  45. package/public/pwa/assets/icons/icon_48.png +0 -0
  46. package/public/pwa/assets/icons/icon_512.png +0 -0
  47. package/public/pwa/manifest.json +54 -0
  48. package/public/pwa/staticwebapp.config.json +6 -0
  49. package/public/pwa/sw.js +109 -0
  50. package/src/base-map-builder.ts +414 -0
  51. package/src/gs-gs2ol.ts +626 -0
  52. package/src/gs-lib.ts +54 -0
  53. package/src/gs-litns.ts +213 -0
  54. package/src/gs-model.ts +393 -0
  55. package/src/gs-ol-adapters.ts +89 -0
  56. package/src/gs-ol2gs.ts +86 -0
  57. package/src/gs-olns.ts +30 -0
  58. package/src/index.ts +15 -0
  59. package/tsconfig.json +23 -0
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
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "navigationFallback": {
3
+ "rewrite": "index.html",
4
+ "exclude": ["*.{css,js,mjs,ts,png,gif,ico,jpg,svg,json,woff2,ttf}"]
5
+ }
6
+ }
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
+
@@ -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
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "navigationFallback": {
3
+ "rewrite": "index.html",
4
+ "exclude": ["*.{css,js,mjs,ts,png,gif,ico,jpg,svg,json,woff2,ttf}"]
5
+ }
6
+ }