chore: exclude local resource artifacts from main sync

This commit is contained in:
2026-05-15 10:16:45 +09:00
parent 442879313f
commit d38d022872
504 changed files with 17074 additions and 3642 deletions

View File

@@ -0,0 +1,294 @@
const PREVIEW_RUNTIME_QUERY_KEY = 'appPreviewMode';
const PREVIEW_RUNTIME_PARENT_ORIGIN_KEY = 'previewParentOrigin';
const PREVIEW_RUNTIME_TOKEN_QUERY_KEY = 'registeredAccessToken';
const PREVIEW_RUNTIME_DEVICE_MODE_QUERY_KEY = 'previewDeviceMode';
const PREVIEW_TARGET_TYPE_QUERY_KEY = 'previewTargetType';
const PREVIEW_TARGET_COMPONENT_ID_QUERY_KEY = 'previewComponentId';
const PREVIEW_TARGET_SAMPLE_ID_QUERY_KEY = 'previewSampleId';
const PREVIEW_RUNTIME_CACHE_RESET_MARKER_KEY = 'work-app.preview-runtime.cache-reset.v1';
const PREVIEW_RUNTIME_CACHE_RESET_PARAM_KEY = '__previewRuntimeCacheReset';
const PREVIEW_RUNTIME_PRESERVED_QUERY_KEYS = [
PREVIEW_RUNTIME_QUERY_KEY,
PREVIEW_RUNTIME_PARENT_ORIGIN_KEY,
PREVIEW_RUNTIME_TOKEN_QUERY_KEY,
PREVIEW_RUNTIME_DEVICE_MODE_QUERY_KEY,
] as const;
export type PreviewTargetDescriptor =
| {
type: 'widget';
componentId: string;
sampleId?: string;
}
| null;
export function isPreviewRuntime() {
if (typeof window === 'undefined') {
return false;
}
return new URLSearchParams(window.location.search).get(PREVIEW_RUNTIME_QUERY_KEY) === '1';
}
export function isPreviewAppOrigin() {
if (typeof window === 'undefined') {
return false;
}
return window.location.origin === resolvePreviewAppOrigin();
}
function readPreviewRuntimeCacheResetMarker() {
if (typeof window === 'undefined') {
return '';
}
try {
return window.sessionStorage.getItem(PREVIEW_RUNTIME_CACHE_RESET_MARKER_KEY)?.trim() ?? '';
} catch {
return '';
}
}
function writePreviewRuntimeCacheResetMarker(value: string) {
if (typeof window === 'undefined') {
return;
}
try {
if (value) {
window.sessionStorage.setItem(PREVIEW_RUNTIME_CACHE_RESET_MARKER_KEY, value);
} else {
window.sessionStorage.removeItem(PREVIEW_RUNTIME_CACHE_RESET_MARKER_KEY);
}
} catch {
// Ignore storage access failures in restricted runtimes.
}
}
function buildPreviewRuntimeLocationKey() {
if (typeof window === 'undefined') {
return '';
}
return `${window.location.origin}${window.location.pathname}`;
}
function buildPreviewRuntimeCacheResetUrl() {
const nextUrl = new URL(window.location.href);
nextUrl.searchParams.set(PREVIEW_RUNTIME_CACHE_RESET_PARAM_KEY, `${Date.now()}`);
return nextUrl.toString();
}
async function clearPreviewRuntimeServiceWorkersAndCaches() {
if (typeof window === 'undefined') {
return false;
}
let changed = false;
if (typeof navigator !== 'undefined' && 'serviceWorker' in navigator) {
try {
const registrations = await navigator.serviceWorker.getRegistrations();
if (registrations.length > 0) {
changed = true;
}
await Promise.all(registrations.map((registration) => registration.unregister().catch(() => false)));
} catch {
// Ignore cleanup failure and continue.
}
}
if ('caches' in window) {
try {
const cacheKeys = await caches.keys();
if (cacheKeys.length > 0) {
changed = true;
}
await Promise.all(cacheKeys.map((cacheKey) => caches.delete(cacheKey).catch(() => false)));
} catch {
// Ignore cache cleanup failure and continue.
}
}
return changed;
}
export async function ensurePreviewRuntimeFreshState() {
if (typeof window === 'undefined' || (!isPreviewRuntime() && !isPreviewAppOrigin())) {
return;
}
const currentLocationKey = buildPreviewRuntimeLocationKey();
const cleanedLocationKey = readPreviewRuntimeCacheResetMarker();
const resetSearchParam = new URL(window.location.href).searchParams.get(PREVIEW_RUNTIME_CACHE_RESET_PARAM_KEY)?.trim() ?? '';
if (cleanedLocationKey === currentLocationKey && !resetSearchParam) {
return;
}
const changed = await clearPreviewRuntimeServiceWorkersAndCaches();
if (!changed) {
if (resetSearchParam) {
const nextUrl = new URL(window.location.href);
nextUrl.searchParams.delete(PREVIEW_RUNTIME_CACHE_RESET_PARAM_KEY);
window.history.replaceState(window.history.state, '', `${nextUrl.pathname}${nextUrl.search}${nextUrl.hash}`);
}
writePreviewRuntimeCacheResetMarker(currentLocationKey);
return;
}
writePreviewRuntimeCacheResetMarker(currentLocationKey);
window.location.replace(buildPreviewRuntimeCacheResetUrl());
await new Promise(() => {
// Keep the bootstrap suspended until the browser navigates away.
});
}
export function getPreviewRuntimeParentOrigin() {
if (typeof window === 'undefined') {
return '';
}
return new URLSearchParams(window.location.search).get(PREVIEW_RUNTIME_PARENT_ORIGIN_KEY)?.trim() ?? '';
}
export function readPreviewRuntimeDeviceModeFromUrl(): 'desktop' | 'mobile' | null {
if (typeof window === 'undefined') {
return null;
}
const value = new URLSearchParams(window.location.search).get(PREVIEW_RUNTIME_DEVICE_MODE_QUERY_KEY)?.trim() ?? '';
if (value === 'desktop' || value === 'mobile') {
return value;
}
return null;
}
export function readPreviewRuntimeTokenFromUrl() {
if (typeof window === 'undefined') {
return '';
}
return new URLSearchParams(window.location.search).get(PREVIEW_RUNTIME_TOKEN_QUERY_KEY)?.trim() ?? '';
}
export function clearPreviewRuntimeTokenFromUrl() {
if (typeof window === 'undefined') {
return;
}
const url = new URL(window.location.href);
if (!url.searchParams.has(PREVIEW_RUNTIME_TOKEN_QUERY_KEY)) {
return;
}
url.searchParams.delete(PREVIEW_RUNTIME_TOKEN_QUERY_KEY);
window.history.replaceState(window.history.state, '', `${url.pathname}${url.search}${url.hash}`);
}
export function resolvePreviewAppOrigin() {
return 'https://preview.sm-home.cloud';
}
export function appendPreviewRuntimeSearch(path: string, sourceSearch = '') {
if (!path) {
return path;
}
const [rawPathname, rawHash = ''] = path.split('#', 2);
const [pathname, rawSearch = ''] = rawPathname.split('?', 2);
const nextSearchParams = new URLSearchParams(rawSearch);
const sourceSearchParams = new URLSearchParams(sourceSearch.startsWith('?') ? sourceSearch.slice(1) : sourceSearch);
PREVIEW_RUNTIME_PRESERVED_QUERY_KEYS.forEach((key) => {
const value = sourceSearchParams.get(key)?.trim() ?? '';
if (value) {
nextSearchParams.set(key, value);
return;
}
nextSearchParams.delete(key);
});
const nextSearch = nextSearchParams.toString();
const nextHash = rawHash ? `#${rawHash}` : '';
return `${pathname}${nextSearch ? `?${nextSearch}` : ''}${nextHash}`;
}
export function readPreviewTargetDescriptorFromUrl(): PreviewTargetDescriptor {
if (typeof window === 'undefined') {
return null;
}
const searchParams = new URLSearchParams(window.location.search);
const targetType = searchParams.get(PREVIEW_TARGET_TYPE_QUERY_KEY)?.trim() ?? '';
if (targetType !== 'widget') {
return null;
}
const componentId = searchParams.get(PREVIEW_TARGET_COMPONENT_ID_QUERY_KEY)?.trim() ?? '';
const sampleId = searchParams.get(PREVIEW_TARGET_SAMPLE_ID_QUERY_KEY)?.trim() ?? '';
if (!componentId) {
return null;
}
return {
type: 'widget',
componentId,
sampleId: sampleId || undefined,
};
}
export function buildPreviewRuntimeUrl(
pathname: string,
search = '',
token = '',
targetDescriptor: PreviewTargetDescriptor = null,
deviceMode: 'desktop' | 'mobile' = 'desktop',
) {
const targetUrl = new URL(pathname || '/', resolvePreviewAppOrigin());
if (search) {
const sourceParams = new URLSearchParams(search.startsWith('?') ? search.slice(1) : search);
sourceParams.forEach((value, key) => {
targetUrl.searchParams.set(key, value);
});
}
targetUrl.searchParams.set(PREVIEW_RUNTIME_QUERY_KEY, '1');
if (typeof window !== 'undefined') {
targetUrl.searchParams.set(PREVIEW_RUNTIME_PARENT_ORIGIN_KEY, window.location.origin);
}
targetUrl.searchParams.set(PREVIEW_RUNTIME_DEVICE_MODE_QUERY_KEY, deviceMode);
if (token.trim()) {
targetUrl.searchParams.set(PREVIEW_RUNTIME_TOKEN_QUERY_KEY, token.trim());
}
if (targetDescriptor?.type === 'widget') {
targetUrl.searchParams.set(PREVIEW_TARGET_TYPE_QUERY_KEY, 'widget');
targetUrl.searchParams.set(PREVIEW_TARGET_COMPONENT_ID_QUERY_KEY, targetDescriptor.componentId);
if (targetDescriptor.sampleId?.trim()) {
targetUrl.searchParams.set(PREVIEW_TARGET_SAMPLE_ID_QUERY_KEY, targetDescriptor.sampleId.trim());
} else {
targetUrl.searchParams.delete(PREVIEW_TARGET_SAMPLE_ID_QUERY_KEY);
}
}
return targetUrl.toString();
}