vatts 2.2.6 → 2.3.0-canary.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/LICENSE +12 -12
- package/README.md +65 -65
- package/dist/builder.js +79 -42
- package/dist/frameworks/FrontCore.d.ts +34 -0
- package/dist/frameworks/FrontCore.js +128 -0
- package/dist/{vue → frameworks/builds}/vue.build.js +1 -1
- package/dist/frameworks/react/client.d.ts +8 -0
- package/dist/{react → frameworks/react}/client.js +14 -14
- package/dist/{react → frameworks/react/components}/Link.js +2 -2
- package/dist/frameworks/react/entry.client.d.ts +14 -0
- package/dist/frameworks/react/entry.client.js +211 -0
- package/dist/frameworks/react/react-elements.d.ts +10 -0
- package/dist/{react → frameworks/renderers}/renderer-react.d.ts +2 -2
- package/dist/{react → frameworks/renderers}/renderer-react.js +53 -86
- package/dist/{vue → frameworks/renderers}/renderer.vue.d.ts +2 -2
- package/dist/frameworks/renderers/renderer.vue.js +193 -0
- package/dist/frameworks/themes/BuildingPage.d.ts +1 -0
- package/dist/frameworks/themes/BuildingPage.js +312 -0
- package/dist/frameworks/themes/DefaultNotFound.d.ts +1 -0
- package/dist/frameworks/themes/DefaultNotFound.js +330 -0
- package/dist/frameworks/themes/ErrorModal.d.ts +1 -0
- package/dist/frameworks/themes/ErrorModal.js +345 -0
- package/dist/frameworks/themes/ServerError.d.ts +1 -0
- package/dist/frameworks/themes/ServerError.js +401 -0
- package/dist/frameworks/themes/VattsDevBadge.d.ts +1 -0
- package/dist/frameworks/themes/VattsDevBadge.js +232 -0
- package/dist/frameworks/vue/App.vue +149 -0
- package/dist/frameworks/vue/client.d.ts +9 -0
- package/dist/{vue → frameworks/vue}/client.js +13 -11
- package/dist/{vue → frameworks/vue/components}/Link.vue +38 -38
- package/dist/{vue → frameworks/vue/components}/image/Image.vue +128 -128
- package/dist/frameworks/vue/entry.client.js +75 -0
- package/dist/global/global.d.ts +179 -180
- package/dist/hotReload.js +77 -77
- package/dist/index.js +12 -1
- package/dist/loaders.js +15 -15
- package/dist/renderer.js +2 -2
- package/dist/renderers/common.js +3 -3
- package/dist/utils/core-go.js +2 -2
- package/dist/utils/utils.js +5 -5
- package/package.json +10 -26
- package/dist/react/BuildingPage.d.ts +0 -2
- package/dist/react/BuildingPage.js +0 -270
- package/dist/react/DefaultNotFound.d.ts +0 -2
- package/dist/react/DefaultNotFound.js +0 -248
- package/dist/react/DevIndicator.d.ts +0 -5
- package/dist/react/DevIndicator.js +0 -203
- package/dist/react/ErrorModal.d.ts +0 -20
- package/dist/react/ErrorModal.js +0 -266
- package/dist/react/client.d.ts +0 -8
- package/dist/react/entry.client.d.ts +0 -6
- package/dist/react/entry.client.js +0 -325
- package/dist/react/server-error.d.ts +0 -8
- package/dist/react/server-error.js +0 -346
- package/dist/vue/App.vue +0 -199
- package/dist/vue/BuildingPage.vue +0 -281
- package/dist/vue/DefaultNotFound.vue +0 -329
- package/dist/vue/DevIndicator.vue +0 -226
- package/dist/vue/ErrorModal.vue +0 -317
- package/dist/vue/client.d.ts +0 -9
- package/dist/vue/entry.client.js +0 -110
- package/dist/vue/renderer.vue.js +0 -387
- package/dist/vue/server-error.vue +0 -351
- /package/dist/{react → frameworks/builds}/react.build.d.ts +0 -0
- /package/dist/{react → frameworks/builds}/react.build.js +0 -0
- /package/dist/{vue → frameworks/builds}/vue.build.d.ts +0 -0
- /package/dist/{react → frameworks/react/components}/Link.d.ts +0 -0
- /package/dist/{react → frameworks/react/components}/image/Image.d.ts +0 -0
- /package/dist/{react → frameworks/react/components}/image/Image.js +0 -0
- /package/dist/{vue → frameworks/vue}/entry.client.d.ts +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component :is="resolvedLayout" v-if="resolvedLayout">
|
|
3
|
+
<component
|
|
4
|
+
:is="resolvedContent"
|
|
5
|
+
v-bind="contentProps"
|
|
6
|
+
:key="`page-${hmrTimestamp}-${currentPathKey}`"
|
|
7
|
+
/>
|
|
8
|
+
</component>
|
|
9
|
+
|
|
10
|
+
<component
|
|
11
|
+
v-else
|
|
12
|
+
:is="resolvedContent"
|
|
13
|
+
v-bind="contentProps"
|
|
14
|
+
:key="`page-${hmrTimestamp}-${currentPathKey}`"
|
|
15
|
+
/>
|
|
16
|
+
|
|
17
|
+
<vatts-dev-badge
|
|
18
|
+
v-if="isDev"
|
|
19
|
+
:has-build-error="!!buildError"
|
|
20
|
+
@click-build-error="isErrorOpen = true"
|
|
21
|
+
></vatts-dev-badge>
|
|
22
|
+
|
|
23
|
+
<vatts-error-modal
|
|
24
|
+
.error="buildError"
|
|
25
|
+
.isOpen="isErrorOpen"
|
|
26
|
+
@close-modal="isErrorOpen = false"
|
|
27
|
+
@copy-log="handleCopyLog"
|
|
28
|
+
></vatts-error-modal>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script setup>
|
|
32
|
+
import { ref, computed, onMounted, onUnmounted, shallowRef, watch, nextTick, defineComponent, h } from 'vue';
|
|
33
|
+
import { router } from '../../client/clientRouter';
|
|
34
|
+
|
|
35
|
+
// Importa a lógica centralizada
|
|
36
|
+
import {
|
|
37
|
+
findRouteForPath, updateDocumentTitle, copyBuildError,
|
|
38
|
+
setupBuildErrorEvents, setupHMREvents, dispatchHmrReady
|
|
39
|
+
} from '../FrontCore';
|
|
40
|
+
|
|
41
|
+
import '../themes/VattsDevBadge';
|
|
42
|
+
import '../themes/ErrorModal';
|
|
43
|
+
|
|
44
|
+
// --- Props ---
|
|
45
|
+
const props = defineProps({
|
|
46
|
+
componentMap: Object,
|
|
47
|
+
routes: Array,
|
|
48
|
+
initialComponentPath: String,
|
|
49
|
+
initialParams: null,
|
|
50
|
+
layoutComponent: null
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// --- Estado ---
|
|
54
|
+
const hmrTimestamp = ref(Date.now());
|
|
55
|
+
const currentPathKey = ref(window.location.pathname);
|
|
56
|
+
const pendingHmrReady = ref(null);
|
|
57
|
+
|
|
58
|
+
const buildError = ref(window.__VATTS_BUILD_ERROR__ || null);
|
|
59
|
+
const isErrorOpen = ref(!!window.__VATTS_BUILD_ERROR__);
|
|
60
|
+
const isDev = process.env.NODE_ENV !== 'production';
|
|
61
|
+
|
|
62
|
+
// Cleanup references for events
|
|
63
|
+
let cleanupErrorEvents;
|
|
64
|
+
let cleanupHmrEvents;
|
|
65
|
+
let unsubscribeRouter;
|
|
66
|
+
|
|
67
|
+
const handleCopyLog = () => copyBuildError(buildError.value);
|
|
68
|
+
|
|
69
|
+
watch(hmrTimestamp, async (timestamp) => {
|
|
70
|
+
if (!pendingHmrReady.value || pendingHmrReady.value.timestamp !== timestamp) return;
|
|
71
|
+
await nextTick();
|
|
72
|
+
dispatchHmrReady(pendingHmrReady.value);
|
|
73
|
+
pendingHmrReady.value = null;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// --- Roteamento ---
|
|
77
|
+
const CurrentPageComponent = shallowRef(null);
|
|
78
|
+
const params = ref({});
|
|
79
|
+
|
|
80
|
+
const updateRoute = () => {
|
|
81
|
+
const currentPath = window.location.pathname.replace("index.html", '');
|
|
82
|
+
currentPathKey.value = currentPath;
|
|
83
|
+
|
|
84
|
+
const match = findRouteForPath(currentPath, props.routes);
|
|
85
|
+
if (match) {
|
|
86
|
+
CurrentPageComponent.value = props.componentMap[match.componentPath];
|
|
87
|
+
params.value = match.params;
|
|
88
|
+
updateDocumentTitle(match.metadata?.title);
|
|
89
|
+
} else {
|
|
90
|
+
CurrentPageComponent.value = null;
|
|
91
|
+
params.value = {};
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// --- Computed ---
|
|
96
|
+
const resolvedContent = computed(() => {
|
|
97
|
+
if (!CurrentPageComponent.value) {
|
|
98
|
+
const NotFoundComponent = window.__VATTS_NOT_FOUND__;
|
|
99
|
+
if (NotFoundComponent) return NotFoundComponent;
|
|
100
|
+
|
|
101
|
+
const { getDefaultNotFound } = window.__VATTS_DEFAULT_NOT_FOUND__;
|
|
102
|
+
return getDefaultNotFound
|
|
103
|
+
? defineComponent({
|
|
104
|
+
render() {
|
|
105
|
+
return h('div', {
|
|
106
|
+
innerHTML: getDefaultNotFound()
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
: 'div';
|
|
111
|
+
}
|
|
112
|
+
return CurrentPageComponent.value;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const contentProps = computed(() => {
|
|
116
|
+
if (!CurrentPageComponent.value) return {};
|
|
117
|
+
return { params: params.value };
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const resolvedLayout = computed(() => props.layoutComponent || null);
|
|
121
|
+
|
|
122
|
+
// --- Lifecycle ---
|
|
123
|
+
onMounted(() => {
|
|
124
|
+
updateRoute();
|
|
125
|
+
|
|
126
|
+
// Usa as funções de eventos do Core
|
|
127
|
+
cleanupErrorEvents = setupBuildErrorEvents(
|
|
128
|
+
(err) => { buildError.value = err; isErrorOpen.value = true; },
|
|
129
|
+
() => { buildError.value = null; isErrorOpen.value = false; }
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
cleanupHmrEvents = setupHMREvents((file, timestamp) => {
|
|
133
|
+
pendingHmrReady.value = { file, timestamp };
|
|
134
|
+
hmrTimestamp.value = timestamp;
|
|
135
|
+
updateRoute();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
window.addEventListener('popstate', updateRoute);
|
|
139
|
+
unsubscribeRouter = router.subscribe(updateRoute);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
onUnmounted(() => {
|
|
143
|
+
if (cleanupErrorEvents) cleanupErrorEvents();
|
|
144
|
+
if (cleanupHmrEvents) cleanupHmrEvents();
|
|
145
|
+
|
|
146
|
+
window.removeEventListener('popstate', updateRoute);
|
|
147
|
+
if (unsubscribeRouter) unsubscribeRouter();
|
|
148
|
+
});
|
|
149
|
+
</script>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Link from "./components/Link.vue";
|
|
2
|
+
export { Link };
|
|
3
|
+
export { RouteConfig, Metadata } from "../../types.ts";
|
|
4
|
+
export { router } from '../../client/clientRouter.ts';
|
|
5
|
+
export { requireDynamic } from '../../client/requireDynamic.ts';
|
|
6
|
+
export { importServer } from '../../client/rpc.ts';
|
|
7
|
+
export { importPhpServer } from '../../client/rpcPhp.ts';
|
|
8
|
+
export { default as Image } from "./components/image/Image.vue";
|
|
9
|
+
export { default as VattsImage } from "./components/image/Image.vue";
|
|
@@ -21,18 +21,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.VattsImage = exports.Image = exports.importPhpServer = exports.importServer = exports.requireDynamic = exports.router = exports.Link = void 0;
|
|
23
23
|
// Este arquivo exporta apenas código seguro para o cliente (navegador)
|
|
24
|
-
const Link_vue_1 = __importDefault(require("./Link.vue"));
|
|
24
|
+
const Link_vue_1 = __importDefault(require("./components/Link.vue"));
|
|
25
25
|
exports.Link = Link_vue_1.default;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
const framework_ts_1 = require("../../api/framework.js");
|
|
27
|
+
var clientRouter_ts_1 = require("../../client/clientRouter.js");
|
|
28
|
+
Object.defineProperty(exports, "router", { enumerable: true, get: function () { return clientRouter_ts_1.router; } });
|
|
29
|
+
var requireDynamic_ts_1 = require("../../client/requireDynamic.js");
|
|
30
|
+
Object.defineProperty(exports, "requireDynamic", { enumerable: true, get: function () { return requireDynamic_ts_1.requireDynamic; } });
|
|
31
|
+
framework_ts_1.cachedFramework == 'react';
|
|
30
32
|
// RPC (client-side)
|
|
31
|
-
var
|
|
32
|
-
Object.defineProperty(exports, "importServer", { enumerable: true, get: function () { return
|
|
33
|
-
var
|
|
34
|
-
Object.defineProperty(exports, "importPhpServer", { enumerable: true, get: function () { return
|
|
35
|
-
var Image_vue_1 = require("./image/Image.vue");
|
|
33
|
+
var rpc_ts_1 = require("../../client/rpc.js");
|
|
34
|
+
Object.defineProperty(exports, "importServer", { enumerable: true, get: function () { return rpc_ts_1.importServer; } });
|
|
35
|
+
var rpcPhp_ts_1 = require("../../client/rpcPhp.js");
|
|
36
|
+
Object.defineProperty(exports, "importPhpServer", { enumerable: true, get: function () { return rpcPhp_ts_1.importPhpServer; } });
|
|
37
|
+
var Image_vue_1 = require("./components/image/Image.vue");
|
|
36
38
|
Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return __importDefault(Image_vue_1).default; } });
|
|
37
|
-
var Image_vue_2 = require("./image/Image.vue");
|
|
39
|
+
var Image_vue_2 = require("./components/image/Image.vue");
|
|
38
40
|
Object.defineProperty(exports, "VattsImage", { enumerable: true, get: function () { return __importDefault(Image_vue_2).default; } });
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
This file is part of the Vatts.js Project.
|
|
3
|
-
Copyright (c) 2026 mfraz
|
|
4
|
-
|
|
5
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
you may not use this file except in compliance with the License.
|
|
7
|
-
You may obtain a copy of the License at
|
|
8
|
-
|
|
9
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
|
|
11
|
-
Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
See the License for the specific language governing permissions and
|
|
15
|
-
limitations under the License.
|
|
16
|
-
-->
|
|
17
|
-
<script setup>
|
|
18
|
-
import { router } from '
|
|
19
|
-
|
|
20
|
-
const props = defineProps({
|
|
21
|
-
href: {
|
|
22
|
-
type: String,
|
|
23
|
-
required: true
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const handleClick = async (e) => {
|
|
28
|
-
e.preventDefault();
|
|
29
|
-
|
|
30
|
-
// Usa o novo sistema de router
|
|
31
|
-
await router.push(props.href);
|
|
32
|
-
};
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<template>
|
|
36
|
-
<a :href="href" @click="handleClick">
|
|
37
|
-
<slot></slot>
|
|
38
|
-
</a>
|
|
1
|
+
<!--
|
|
2
|
+
This file is part of the Vatts.js Project.
|
|
3
|
+
Copyright (c) 2026 mfraz
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
-->
|
|
17
|
+
<script setup>
|
|
18
|
+
import { router } from '../../../client/clientRouter';
|
|
19
|
+
|
|
20
|
+
const props = defineProps({
|
|
21
|
+
href: {
|
|
22
|
+
type: String,
|
|
23
|
+
required: true
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const handleClick = async (e) => {
|
|
28
|
+
e.preventDefault();
|
|
29
|
+
|
|
30
|
+
// Usa o novo sistema de router
|
|
31
|
+
await router.push(props.href);
|
|
32
|
+
};
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<a :href="href" @click="handleClick">
|
|
37
|
+
<slot></slot>
|
|
38
|
+
</a>
|
|
39
39
|
</template>
|
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
* This file is part of the Vatts.js Project.
|
|
3
|
-
* Copyright (c) 2026 mfraz
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
-->
|
|
17
|
-
|
|
18
|
-
<script setup>
|
|
19
|
-
import { computed } from 'vue';
|
|
20
|
-
|
|
21
|
-
const props = defineProps({
|
|
22
|
-
src: {
|
|
23
|
-
type: String,
|
|
24
|
-
required: true
|
|
25
|
-
},
|
|
26
|
-
width: [Number, String],
|
|
27
|
-
height: [Number, String],
|
|
28
|
-
quality: {
|
|
29
|
-
type: Number,
|
|
30
|
-
default: 75
|
|
31
|
-
},
|
|
32
|
-
priority: {
|
|
33
|
-
type: Boolean,
|
|
34
|
-
default: false
|
|
35
|
-
},
|
|
36
|
-
alt: {
|
|
37
|
-
type: String,
|
|
38
|
-
default: ""
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const getBaseUrl = () => {
|
|
43
|
-
if (typeof window === "undefined") return null;
|
|
44
|
-
return window.location.origin;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const optimizedSrc = computed(() => {
|
|
48
|
-
const baseUrl = getBaseUrl();
|
|
49
|
-
const { src: rawSrc, quality, width, height } = props;
|
|
50
|
-
|
|
51
|
-
// Normaliza o prop `src` primeiro para evitar o erro de inicialização
|
|
52
|
-
const src = (rawSrc && typeof rawSrc === 'string') ? rawSrc : (rawSrc && typeof rawSrc === 'object' ? (rawSrc.src || rawSrc.default || String(rawSrc)) : rawSrc);
|
|
53
|
-
|
|
54
|
-
// Agora a verificação do valor normalizado funciona perfeitamente
|
|
55
|
-
if(!src || (typeof src === "object" && src && (src.length === 0 || Object.keys(src).length === 0))) {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Detecta se estamos em modo de export estático (SSG). Neste caso o endpoint de otimização não estará disponível
|
|
60
|
-
const isExportMode =
|
|
61
|
-
(
|
|
62
|
-
typeof window !== 'undefined' &&
|
|
63
|
-
(
|
|
64
|
-
window.__VATTS_MODE__ === 'export' ||
|
|
65
|
-
(window.__VATTS && window.__VATTS.mode === 'export') ||
|
|
66
|
-
window.__VATTS_EXPORT__ === true
|
|
67
|
-
)
|
|
68
|
-
) ||
|
|
69
|
-
(
|
|
70
|
-
typeof process !== 'undefined' &&
|
|
71
|
-
process.env?.VATTS_MODE === 'exported'
|
|
72
|
-
);
|
|
73
|
-
// Se a imagem for Base64 (pequena) ou externa (http), ou se estamos em modo export, não otimizamos via backend local
|
|
74
|
-
const isOptimizable = src && typeof src === 'string' && !src.startsWith('data:') && ((baseUrl && src.startsWith(baseUrl)) || !src.startsWith('http')) && !isExportMode;
|
|
75
|
-
|
|
76
|
-
if (!isOptimizable) return src;
|
|
77
|
-
|
|
78
|
-
let path = src;
|
|
79
|
-
if (baseUrl && path.startsWith(baseUrl)) {
|
|
80
|
-
path = path.slice(baseUrl.length) || '/';
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const params = new URLSearchParams();
|
|
84
|
-
params.set('url', path);
|
|
85
|
-
|
|
86
|
-
// Tratamento para remover "px" se o usuário passar string
|
|
87
|
-
if (width) {
|
|
88
|
-
const w = String(width).replace('px', '');
|
|
89
|
-
if (!isNaN(Number(w))) params.set('w', w);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (height) {
|
|
93
|
-
const h = String(height).replace('px', '');
|
|
94
|
-
if (!isNaN(Number(h))) params.set('h', h);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (quality) params.set('q', quality.toString());
|
|
98
|
-
|
|
99
|
-
return `/_vatts/image?${params.toString()}`;
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const baseStyle = computed(() => {
|
|
103
|
-
return {
|
|
104
|
-
width: props.width ? (typeof props.width === 'number' ? `${props.width}px` : props.width) : 'auto',
|
|
105
|
-
height: props.height ? (typeof props.height === 'number' ? `${props.height}px` : props.height) : 'auto',
|
|
106
|
-
};
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Remove "px" para os atributos nativos width/height da tag img
|
|
110
|
-
const cleanDimension = (val) => {
|
|
111
|
-
if (typeof val === 'string') return val.replace('px', '');
|
|
112
|
-
return val;
|
|
113
|
-
};
|
|
114
|
-
</script>
|
|
115
|
-
|
|
116
|
-
<template>
|
|
117
|
-
<img
|
|
118
|
-
v-if="optimizedSrc !== null"
|
|
119
|
-
v-bind="$attrs"
|
|
120
|
-
:src="optimizedSrc"
|
|
121
|
-
:alt="alt"
|
|
122
|
-
:loading="priority ? 'eager' : 'lazy'"
|
|
123
|
-
:decoding="priority ? 'sync' : 'async'"
|
|
124
|
-
:width="cleanDimension(width)"
|
|
125
|
-
:height="cleanDimension(height)"
|
|
126
|
-
:style="baseStyle"
|
|
127
|
-
class="vatts-image"
|
|
128
|
-
/>
|
|
1
|
+
<!--
|
|
2
|
+
* This file is part of the Vatts.js Project.
|
|
3
|
+
* Copyright (c) 2026 mfraz
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
-->
|
|
17
|
+
|
|
18
|
+
<script setup>
|
|
19
|
+
import { computed } from 'vue';
|
|
20
|
+
|
|
21
|
+
const props = defineProps({
|
|
22
|
+
src: {
|
|
23
|
+
type: String,
|
|
24
|
+
required: true
|
|
25
|
+
},
|
|
26
|
+
width: [Number, String],
|
|
27
|
+
height: [Number, String],
|
|
28
|
+
quality: {
|
|
29
|
+
type: Number,
|
|
30
|
+
default: 75
|
|
31
|
+
},
|
|
32
|
+
priority: {
|
|
33
|
+
type: Boolean,
|
|
34
|
+
default: false
|
|
35
|
+
},
|
|
36
|
+
alt: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: ""
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const getBaseUrl = () => {
|
|
43
|
+
if (typeof window === "undefined") return null;
|
|
44
|
+
return window.location.origin;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const optimizedSrc = computed(() => {
|
|
48
|
+
const baseUrl = getBaseUrl();
|
|
49
|
+
const { src: rawSrc, quality, width, height } = props;
|
|
50
|
+
|
|
51
|
+
// Normaliza o prop `src` primeiro para evitar o erro de inicialização
|
|
52
|
+
const src = (rawSrc && typeof rawSrc === 'string') ? rawSrc : (rawSrc && typeof rawSrc === 'object' ? (rawSrc.src || rawSrc.default || String(rawSrc)) : rawSrc);
|
|
53
|
+
|
|
54
|
+
// Agora a verificação do valor normalizado funciona perfeitamente
|
|
55
|
+
if(!src || (typeof src === "object" && src && (src.length === 0 || Object.keys(src).length === 0))) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Detecta se estamos em modo de export estático (SSG). Neste caso o endpoint de otimização não estará disponível
|
|
60
|
+
const isExportMode =
|
|
61
|
+
(
|
|
62
|
+
typeof window !== 'undefined' &&
|
|
63
|
+
(
|
|
64
|
+
window.__VATTS_MODE__ === 'export' ||
|
|
65
|
+
(window.__VATTS && window.__VATTS.mode === 'export') ||
|
|
66
|
+
window.__VATTS_EXPORT__ === true
|
|
67
|
+
)
|
|
68
|
+
) ||
|
|
69
|
+
(
|
|
70
|
+
typeof process !== 'undefined' &&
|
|
71
|
+
process.env?.VATTS_MODE === 'exported'
|
|
72
|
+
);
|
|
73
|
+
// Se a imagem for Base64 (pequena) ou externa (http), ou se estamos em modo export, não otimizamos via backend local
|
|
74
|
+
const isOptimizable = src && typeof src === 'string' && !src.startsWith('data:') && ((baseUrl && src.startsWith(baseUrl)) || !src.startsWith('http')) && !isExportMode;
|
|
75
|
+
|
|
76
|
+
if (!isOptimizable) return src;
|
|
77
|
+
|
|
78
|
+
let path = src;
|
|
79
|
+
if (baseUrl && path.startsWith(baseUrl)) {
|
|
80
|
+
path = path.slice(baseUrl.length) || '/';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const params = new URLSearchParams();
|
|
84
|
+
params.set('url', path);
|
|
85
|
+
|
|
86
|
+
// Tratamento para remover "px" se o usuário passar string
|
|
87
|
+
if (width) {
|
|
88
|
+
const w = String(width).replace('px', '');
|
|
89
|
+
if (!isNaN(Number(w))) params.set('w', w);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (height) {
|
|
93
|
+
const h = String(height).replace('px', '');
|
|
94
|
+
if (!isNaN(Number(h))) params.set('h', h);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (quality) params.set('q', quality.toString());
|
|
98
|
+
|
|
99
|
+
return `/_vatts/image?${params.toString()}`;
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const baseStyle = computed(() => {
|
|
103
|
+
return {
|
|
104
|
+
width: props.width ? (typeof props.width === 'number' ? `${props.width}px` : props.width) : 'auto',
|
|
105
|
+
height: props.height ? (typeof props.height === 'number' ? `${props.height}px` : props.height) : 'auto',
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Remove "px" para os atributos nativos width/height da tag img
|
|
110
|
+
const cleanDimension = (val) => {
|
|
111
|
+
if (typeof val === 'string') return val.replace('px', '');
|
|
112
|
+
return val;
|
|
113
|
+
};
|
|
114
|
+
</script>
|
|
115
|
+
|
|
116
|
+
<template>
|
|
117
|
+
<img
|
|
118
|
+
v-if="optimizedSrc !== null"
|
|
119
|
+
v-bind="$attrs"
|
|
120
|
+
:src="optimizedSrc"
|
|
121
|
+
:alt="alt"
|
|
122
|
+
:loading="priority ? 'eager' : 'lazy'"
|
|
123
|
+
:decoding="priority ? 'sync' : 'async'"
|
|
124
|
+
:width="cleanDimension(width)"
|
|
125
|
+
:height="cleanDimension(height)"
|
|
126
|
+
:style="baseStyle"
|
|
127
|
+
class="vatts-image"
|
|
128
|
+
/>
|
|
129
129
|
</template>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/*
|
|
7
|
+
* This file is part of the Vatts.js Project.
|
|
8
|
+
* Copyright (c) 2026 mfraz
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
11
|
+
* you may not use this file except in compliance with the License.
|
|
12
|
+
* You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
const vue_1 = require("vue");
|
|
23
|
+
const App_vue_1 = __importDefault(require("./App.vue"));
|
|
24
|
+
// Importa a lógica centralizada (agora usando findRouteForPath ao invés de getInitialClientData)
|
|
25
|
+
const FrontCore_1 = require("../FrontCore");
|
|
26
|
+
function initializeClient() {
|
|
27
|
+
try {
|
|
28
|
+
// Resolve a rota e params inicial calculando diretamente no lado do cliente
|
|
29
|
+
// a partir da injeção global do esbuild
|
|
30
|
+
const routes = window.__VATTS_ROUTES__ || [];
|
|
31
|
+
const currentPath = window.location.pathname.replace("index.html", '');
|
|
32
|
+
const match = (0, FrontCore_1.findRouteForPath)(currentPath, routes);
|
|
33
|
+
const initialComponentPath = match ? match.componentPath : '__404__';
|
|
34
|
+
const initialParams = match ? match.params : {};
|
|
35
|
+
const componentMap = {};
|
|
36
|
+
if (window.__VATTS_COMPONENTS__) {
|
|
37
|
+
Object.assign(componentMap, window.__VATTS_COMPONENTS__);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
console.warn('[Vatts Vue] No components found in window.__VATTS_COMPONENTS__');
|
|
41
|
+
}
|
|
42
|
+
const container = document.getElementById('root');
|
|
43
|
+
if (!container)
|
|
44
|
+
throw new Error('Container #root not found.');
|
|
45
|
+
if (window.__VATTS_APP__) {
|
|
46
|
+
try {
|
|
47
|
+
window.__VATTS_APP__.unmount();
|
|
48
|
+
container.innerHTML = '';
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
console.warn('[Vatts Vue] Warning during unmount:', e);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const app = (0, vue_1.createApp)(App_vue_1.default, {
|
|
55
|
+
componentMap,
|
|
56
|
+
routes, // Passamos as rotas globais
|
|
57
|
+
initialComponentPath, // Passamos o path resolvido
|
|
58
|
+
initialParams, // Passamos os parâmetros da URL
|
|
59
|
+
layoutComponent: window.__VATTS_LAYOUT__
|
|
60
|
+
});
|
|
61
|
+
// Configuração para suportar os Web Components de desenvolvimento do Vatts
|
|
62
|
+
app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('vatts-');
|
|
63
|
+
window.__VATTS_APP__ = app;
|
|
64
|
+
app.mount(container);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
(0, FrontCore_1.renderCriticalError)(error, 'Vue');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (document.readyState === 'loading') {
|
|
71
|
+
document.addEventListener('DOMContentLoaded', initializeClient);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
setTimeout(initializeClient, 0);
|
|
75
|
+
}
|