Skip to content

Commit 63d0108

Browse files
authored
avoid bundle of index.js if there is a change that is not a .ts file. (#1145)
* avoid bundle of index.js if there is a change that is not a .ts file. change delay to 800ms * avoid re-writing entity-names all the time when there is no change * add another validation to avoid reading the file every time * do not merge this commit * avoid updating the transform if there is no changes * remvoe unnecessary code * fix change files from node_modules * fix path with special characters * remove logs
1 parent 2e39266 commit 63d0108

6 files changed

Lines changed: 68 additions & 39 deletions

File tree

packages/@dcl/inspector/src/lib/babylon/decentraland/gizmo-manager.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { SceneContext } from './SceneContext'
1818
import { PatchedGizmoManager } from './gizmo-patch'
1919
import { ROOT } from '../../sdk/tree'
2020
import { LEFT_BUTTON } from './mouse-utils'
21+
import { recursiveCheck } from 'jest-matcher-deep-close-to/lib/recursiveCheck'
2122

2223
const GIZMO_DUMMY_NODE = 'GIZMO_DUMMY_NODE'
2324

@@ -160,12 +161,16 @@ export function createGizmoManager(context: SceneContext) {
160161

161162
function updateEntityTransform(entity: Entity, newTransform: TransformType) {
162163
const { position, scale, rotation, parent } = newTransform
163-
context.operations.updateValue(context.Transform, entity, {
164+
const transform = {
164165
position: DclVector3.create(position.x, position.y, position.z),
165166
rotation: DclQuaternion.create(rotation.x, rotation.y, rotation.z, rotation.w),
166167
scale: DclVector3.create(scale.x, scale.y, scale.z),
167168
parent
168-
})
169+
}
170+
if (!recursiveCheck(context.Transform.get(entity), transform, 2)) {
171+
return
172+
}
173+
context.operations.updateValue(context.Transform, entity, transform)
169174
}
170175

171176
/**

packages/@dcl/inspector/src/lib/data-layer/host/utils/engine-to-composite.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ export function dumpEngineToCrdtCommands(engine: IEngine): Uint8Array {
141141
* @param fs FileSystem interface for writing the file
142142
* @returns Promise that resolves when the file has been written
143143
*/
144+
145+
let __ENTITY_NAMES_CACHE: Set<string> = new Set()
144146
export async function generateEntityNamesType(
145147
engine: IEngine,
146148
outputPath: string = 'scene-entity-names.d.ts',
@@ -149,7 +151,6 @@ export async function generateEntityNamesType(
149151
): Promise<void> {
150152
try {
151153
// Find the Name component definition
152-
153154
const NameComponent: typeof Name = engine.getComponentOrNull(Name.componentId) as typeof Name
154155

155156
if (!NameComponent) {
@@ -166,9 +167,16 @@ export async function generateEntityNamesType(
166167

167168
// Sort names for consistency
168169
names.sort()
170+
const namesSet = new Set(names)
171+
172+
if (namesSet.difference(__ENTITY_NAMES_CACHE).size === 0) {
173+
return
174+
}
175+
176+
__ENTITY_NAMES_CACHE = namesSet
169177

170178
// Remove duplicates
171-
const uniqueNames = Array.from(new Set(names))
179+
const uniqueNames = Array.from(namesSet)
172180

173181
// Generate valid TypeScript identifiers and handle duplicates in a single pass
174182
const validNameMap = new Map<string, string>()
@@ -208,9 +216,19 @@ export async function generateEntityNamesType(
208216

209217
fileContent += `} \n`
210218

211-
// Write to file
219+
// Check if file exists and compare content before writing
220+
const fileExists = await fs.existFile(outputPath)
221+
if (fileExists) {
222+
const existingContent = (await fs.readFile(outputPath)).toString('utf-8')
223+
if (existingContent === fileContent) {
224+
// Content is identical, no need to write
225+
return
226+
}
227+
}
228+
229+
// Write to file only if content is different or file doesn't exist
212230
await fs.writeFile(outputPath, Buffer.from(fileContent, 'utf-8'))
213231
} catch (e) {
214-
console.error('Fail to generate entity names types', e)
232+
console.error(`Fail to generate entity names types: ${e}\n`)
215233
}
216234
}

packages/@dcl/sdk-commands/src/commands/start/server/file-watch-notifier.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,23 @@ import {
1111
WsSceneMessage,
1212
UpdateModelType
1313
} from '@dcl/protocol/out-js/decentraland/sdk/development/local_development.gen'
14+
import { debounce } from '../../../logic/debounce'
1415

15-
function debounce<T extends (...args: any[]) => void>(callback: T, delay: number) {
16-
let debounceTimer: NodeJS.Timeout
17-
return (...args: Parameters<T>) => {
18-
clearTimeout(debounceTimer)
19-
debounceTimer = setTimeout(() => callback(...args), delay)
20-
}
21-
}
2216
/**
2317
* This function gets file modification events and sends them to all the connected
2418
* websockets, it is used to hot-reload assets of the scene.
2519
*
2620
* IMPORTANT: this is a legacy protocol and needs to be revisited for SDK7
2721
*/
2822
export async function wireFileWatcherToWebSockets(
29-
components: Pick<PreviewComponents, 'fs' | 'ws'>,
23+
components: Pick<PreviewComponents, 'fs' | 'ws' | 'logger'>,
3024
projectRoot: string,
3125
projectKind: ProjectUnion['kind'],
3226
desktopClient: boolean
3327
) {
3428
const ignored = await getDCLIgnorePatterns(components, projectRoot)
3529
const sceneId = b64HashingFunction(projectRoot)
30+
3631
chokidar
3732
.watch(path.resolve(projectRoot), {
3833
atomic: false,
@@ -52,7 +47,7 @@ export async function wireFileWatcherToWebSockets(
5247
updateScene(sceneId, file)
5348
}
5449
return __LEGACY__updateScene(projectRoot, sceneUpdateClients, projectKind)
55-
}, 500)
50+
}, 800)
5651
)
5752
}
5853

packages/@dcl/sdk-commands/src/logic/bundle.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import { printProgressInfo, printProgressStep, printWarning } from './beautiful-
1616
import { CliError } from './error'
1717
import { getAllComposites } from './composite'
1818
import { isEditorScene } from './project-validations'
19+
import { watch } from 'chokidar'
20+
import { debounce } from './debounce'
1921

2022
export type BundleComponents = Pick<CliComponents, 'logger' | 'fs'>
2123

@@ -197,9 +199,34 @@ export async function bundleSingleProject(components: BundleComponents, options:
197199

198200
/* istanbul ignore if */
199201
if (options.watch) {
200-
await context.watch({})
202+
// Instead of using esbuild's watch, we create our own watcher
203+
const watcher = watch(path.resolve(options.workingDirectory), {
204+
ignored: ['**/dist/**', '**/*.crdt', '**/*.composite', path.resolve(options.outputFile)],
205+
ignoreInitial: true
206+
})
207+
208+
const debouncedRebuild = debounce(async () => {
209+
try {
210+
await context.rebuild()
211+
printProgressInfo(components.logger, `Bundle saved ${colors.bold(options.outputFile)}`)
212+
} catch (err: any) {
213+
/* istanbul ignore next */
214+
components.logger.error(err.toString())
215+
}
216+
}, 100)
217+
218+
watcher.on('all', async (event, filePath) => {
219+
// Only rebuild for TypeScript and JavaScript files
220+
if (/\.(ts|tsx|js|jsx)$/.test(filePath)) {
221+
printProgressInfo(components.logger, `File ${filePath} changed, rebuilding...`)
222+
debouncedRebuild()
223+
}
224+
})
201225

226+
// Do initial build
227+
await context.rebuild()
202228
printProgressInfo(components.logger, `Bundle saved ${colors.bold(options.outputFile)}`)
229+
printProgressInfo(components.logger, `The compiler is watching for changes`)
203230
} else {
204231
try {
205232
await context.rebuild()
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function debounce<T extends (...args: any[]) => void>(callback: T, delay: number) {
2+
let debounceTimer: NodeJS.Timeout
3+
return (...args: Parameters<T>) => {
4+
clearTimeout(debounceTimer)
5+
debounceTimer = setTimeout(() => callback(...args), delay)
6+
}
7+
}

scripts/prepare.spec.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -129,26 +129,3 @@ function installCrossDependencies(...paths: string[]) {
129129
}
130130
}
131131
}
132-
133-
function checkNoLocalPackages(...paths: string[]) {
134-
for (const path of paths) {
135-
const packageJson = resolve(path, 'package.json')
136-
it('checking ' + packageJson, async () => {
137-
const { dependencies, devDependencies } = JSON.parse(await readFile(packageJson, 'utf-8'))
138-
const errors: string[] = []
139-
for (const [key, value] of Object.entries({ ...dependencies, ...devDependencies } as Record<string, string>)) {
140-
if (
141-
value.startsWith('file:') ||
142-
value.startsWith('http:') ||
143-
value.startsWith('https:') ||
144-
value.startsWith('git:')
145-
) {
146-
errors.push(`Dependency ${key} is not pointing to a published version: ${value}`)
147-
}
148-
}
149-
if (errors.length) {
150-
throw new Error(errors.join('\n'))
151-
}
152-
})
153-
}
154-
}

0 commit comments

Comments
 (0)