sh3-core 0.19.0 → 0.19.1
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/gestures/gestureRegistry.test.js +1 -0
- package/dist/layout/compact/CarouselTabs.svelte +3 -2
- package/dist/shards/activate.svelte.js +8 -2
- package/dist/shards/ctx-fetch.test.js +70 -0
- package/dist/shards/types.d.ts +16 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import type { TabsNode, TabEntry, TreeRootRef } from '../types';
|
|
19
19
|
import SlotContainer from '../SlotContainer.svelte';
|
|
20
20
|
import SlotDropZone from '../SlotDropZone.svelte';
|
|
21
|
-
import { claim, revoke } from '../../gestures/pointerClaim';
|
|
21
|
+
import { claim, revoke, isOwner } from '../../gestures/pointerClaim';
|
|
22
22
|
import { ancestorCount } from '../../gestures';
|
|
23
23
|
|
|
24
24
|
let {
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
// Multi-touch (pinch-zoom etc.) is not a swipe — bail.
|
|
126
126
|
if (ev.isPrimary === false) return;
|
|
127
127
|
const depth = containerEl ? ancestorCount(containerEl) : 0;
|
|
128
|
-
const claimGranted = claim(ev.pointerId, { ownerId: 'sh3:carousel', axis: 'x', priority: '
|
|
128
|
+
const claimGranted = claim(ev.pointerId, { ownerId: 'sh3:carousel', axis: 'x', priority: 'normal', depth });
|
|
129
129
|
if (!claimGranted) return;
|
|
130
130
|
activePointerId = ev.pointerId;
|
|
131
131
|
downSnap = { id: ev.pointerId, x: ev.clientX, y: ev.clientY, t: performance.now() };
|
|
@@ -140,6 +140,7 @@
|
|
|
140
140
|
|
|
141
141
|
function onPointerMove(ev: PointerEvent) {
|
|
142
142
|
if (!downSnap || ev.pointerId !== downSnap.id) return;
|
|
143
|
+
if (!isOwner(ev.pointerId, 'sh3:carousel')) { endGesture(); return; }
|
|
143
144
|
const dx = ev.clientX - downSnap.x;
|
|
144
145
|
const dy = ev.clientY - downSnap.y;
|
|
145
146
|
if (!claimed) {
|
|
@@ -160,12 +160,18 @@ export async function activateShard(id, opts) {
|
|
|
160
160
|
return handle;
|
|
161
161
|
},
|
|
162
162
|
fetch(path, init) {
|
|
163
|
+
return apiFetch(this.resolveUrl(path), init);
|
|
164
|
+
},
|
|
165
|
+
get serverUrl() {
|
|
166
|
+
return getEnvServerUrl();
|
|
167
|
+
},
|
|
168
|
+
resolveUrl(path) {
|
|
163
169
|
const isAbsolute = path.startsWith('http://') || path.startsWith('https://');
|
|
164
170
|
if (isAbsolute)
|
|
165
|
-
return
|
|
171
|
+
return path;
|
|
166
172
|
const base = getEnvServerUrl();
|
|
167
173
|
const sep = path.startsWith('/') ? '' : '/';
|
|
168
|
-
return
|
|
174
|
+
return `${base}${sep}${path}`;
|
|
169
175
|
},
|
|
170
176
|
env(defaults) {
|
|
171
177
|
if (envState.proxy) {
|
|
@@ -64,3 +64,73 @@ describe('ctx.fetch', () => {
|
|
|
64
64
|
expect(calls[0]).toBe('https://example.com/api/baz');
|
|
65
65
|
});
|
|
66
66
|
});
|
|
67
|
+
describe('ctx.serverUrl', () => {
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
__resetShardRegistryForTest();
|
|
70
|
+
__resetViewRegistryForTest();
|
|
71
|
+
__setDocumentBackend(new MemoryDocumentBackend());
|
|
72
|
+
__setTenantId('tenant-test');
|
|
73
|
+
__setEnvServerUrl('https://example.com');
|
|
74
|
+
});
|
|
75
|
+
afterEach(() => {
|
|
76
|
+
__setEnvServerUrl('');
|
|
77
|
+
});
|
|
78
|
+
it('returns the configured server base URL', async () => {
|
|
79
|
+
let captured = null;
|
|
80
|
+
registerShard({
|
|
81
|
+
manifest: { id: 'test', label: 'test', version: '0.0.0', views: [] },
|
|
82
|
+
activate(ctx) { captured = ctx; },
|
|
83
|
+
});
|
|
84
|
+
await activateShard('test');
|
|
85
|
+
expect(captured.serverUrl).toBe('https://example.com');
|
|
86
|
+
});
|
|
87
|
+
it('returns empty string when no server URL is configured', async () => {
|
|
88
|
+
__setEnvServerUrl('');
|
|
89
|
+
let captured = null;
|
|
90
|
+
registerShard({
|
|
91
|
+
manifest: { id: 'test', label: 'test', version: '0.0.0', views: [] },
|
|
92
|
+
activate(ctx) { captured = ctx; },
|
|
93
|
+
});
|
|
94
|
+
await activateShard('test');
|
|
95
|
+
expect(captured.serverUrl).toBe('');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
describe('ctx.resolveUrl', () => {
|
|
99
|
+
beforeEach(() => {
|
|
100
|
+
__resetShardRegistryForTest();
|
|
101
|
+
__resetViewRegistryForTest();
|
|
102
|
+
__setDocumentBackend(new MemoryDocumentBackend());
|
|
103
|
+
__setTenantId('tenant-test');
|
|
104
|
+
__setEnvServerUrl('https://example.com');
|
|
105
|
+
});
|
|
106
|
+
afterEach(() => {
|
|
107
|
+
__setEnvServerUrl('');
|
|
108
|
+
});
|
|
109
|
+
it('resolves a relative path to an absolute URL', async () => {
|
|
110
|
+
let captured = null;
|
|
111
|
+
registerShard({
|
|
112
|
+
manifest: { id: 'test', label: 'test', version: '0.0.0', views: [] },
|
|
113
|
+
activate(ctx) { captured = ctx; },
|
|
114
|
+
});
|
|
115
|
+
await activateShard('test');
|
|
116
|
+
expect(captured.resolveUrl('/api/foo')).toBe('https://example.com/api/foo');
|
|
117
|
+
});
|
|
118
|
+
it('passes absolute URLs through unchanged', async () => {
|
|
119
|
+
let captured = null;
|
|
120
|
+
registerShard({
|
|
121
|
+
manifest: { id: 'test', label: 'test', version: '0.0.0', views: [] },
|
|
122
|
+
activate(ctx) { captured = ctx; },
|
|
123
|
+
});
|
|
124
|
+
await activateShard('test');
|
|
125
|
+
expect(captured.resolveUrl('https://other.example.com/ws')).toBe('https://other.example.com/ws');
|
|
126
|
+
});
|
|
127
|
+
it('prepends a slash to bare relative paths', async () => {
|
|
128
|
+
let captured = null;
|
|
129
|
+
registerShard({
|
|
130
|
+
manifest: { id: 'test', label: 'test', version: '0.0.0', views: [] },
|
|
131
|
+
activate(ctx) { captured = ctx; },
|
|
132
|
+
});
|
|
133
|
+
await activateShard('test');
|
|
134
|
+
expect(captured.resolveUrl('api/ws')).toBe('https://example.com/api/ws');
|
|
135
|
+
});
|
|
136
|
+
});
|
package/dist/shards/types.d.ts
CHANGED
|
@@ -218,6 +218,22 @@ export interface ShardContext {
|
|
|
218
218
|
* @param init - Standard RequestInit.
|
|
219
219
|
*/
|
|
220
220
|
fetch(path: string, init?: RequestInit): Promise<Response>;
|
|
221
|
+
/**
|
|
222
|
+
* The configured server base URL (e.g. `https://my-sh3.example.com`).
|
|
223
|
+
* Empty string when running local-only (no remote server).
|
|
224
|
+
* Use this as the `BaseAddress` for non-fetch HTTP clients (e.g. WASM .NET
|
|
225
|
+
* `HttpClient`) that cannot go through `ctx.fetch`.
|
|
226
|
+
*/
|
|
227
|
+
readonly serverUrl: string;
|
|
228
|
+
/**
|
|
229
|
+
* Resolve a path to an absolute URL against the configured server, using
|
|
230
|
+
* the same rules as `ctx.fetch` but without making a request. Useful for
|
|
231
|
+
* WebSocket URLs and any transport that bypasses `ctx.fetch`.
|
|
232
|
+
*
|
|
233
|
+
* @param path - Relative `/api/...` path or fully-qualified URL.
|
|
234
|
+
* @returns Absolute URL string.
|
|
235
|
+
*/
|
|
236
|
+
resolveUrl(path: string): string;
|
|
221
237
|
/**
|
|
222
238
|
* Declare environment state for this shard and receive a hydrated snapshot.
|
|
223
239
|
* Env state is server-authoritative, fetched once at activation, and
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Auto-generated from package.json — do not edit manually. */
|
|
2
|
-
export declare const VERSION = "0.19.
|
|
2
|
+
export declare const VERSION = "0.19.1";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Auto-generated from package.json — do not edit manually. */
|
|
2
|
-
export const VERSION = '0.19.
|
|
2
|
+
export const VERSION = '0.19.1';
|