diff --git a/package-lock.json b/package-lock.json index 3631dde14..04305ea35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@actions/core": "^1.10.0", - "@dcl/protocol": "1.0.0-9959547690.commit-67e81c4", + "@dcl/protocol": "1.0.0-10043247792.commit-428d1eb", "@dcl/quickjs-emscripten": "^0.21.0-3680274614.commit-1808aa1", "@dcl/ts-proto": "1.153.0", "@types/fs-extra": "^9.0.12", @@ -577,9 +577,9 @@ } }, "node_modules/@dcl/protocol": { - "version": "1.0.0-9959547690.commit-67e81c4", - "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-9959547690.commit-67e81c4.tgz", - "integrity": "sha512-o6D3wiYOgKwsHn6Wvv7vj5dnzmkMtJIZad3nOcoAbushmuvpRHbC0CirwkjtFanrqMlBrFq/Xv4X9PQvvHY+HA==", + "version": "1.0.0-10043247792.commit-428d1eb", + "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-10043247792.commit-428d1eb.tgz", + "integrity": "sha512-rHXQhXBJawMpPEZACp2fdHEK4ZhKw3xJaVz3IpzHdrxYWdPThKf2pUkYZZ/2iQ248GrlDRM9G7ou7lOk8SwOzw==", "dependencies": { "@dcl/ts-proto": "1.154.0" } @@ -8232,9 +8232,9 @@ } }, "@dcl/protocol": { - "version": "1.0.0-9959547690.commit-67e81c4", - "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-9959547690.commit-67e81c4.tgz", - "integrity": "sha512-o6D3wiYOgKwsHn6Wvv7vj5dnzmkMtJIZad3nOcoAbushmuvpRHbC0CirwkjtFanrqMlBrFq/Xv4X9PQvvHY+HA==", + "version": "1.0.0-10043247792.commit-428d1eb", + "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-10043247792.commit-428d1eb.tgz", + "integrity": "sha512-rHXQhXBJawMpPEZACp2fdHEK4ZhKw3xJaVz3IpzHdrxYWdPThKf2pUkYZZ/2iQ248GrlDRM9G7ou7lOk8SwOzw==", "requires": { "@dcl/ts-proto": "1.154.0" }, diff --git a/package.json b/package.json index 7d0bc72a7..29b46a358 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "bugs": "https://github.com/decentraland/js-sdk-toolchain/issues", "dependencies": { "@actions/core": "^1.10.0", - "@dcl/protocol": "1.0.0-9959547690.commit-67e81c4", + "@dcl/protocol": "1.0.0-10043247792.commit-428d1eb", "@dcl/quickjs-emscripten": "^0.21.0-3680274614.commit-1808aa1", "@dcl/ts-proto": "1.153.0", "@types/fs-extra": "^9.0.12", diff --git a/packages/@dcl/sdk-commands/package-lock.json b/packages/@dcl/sdk-commands/package-lock.json index c324c4e80..dd53f329f 100644 --- a/packages/@dcl/sdk-commands/package-lock.json +++ b/packages/@dcl/sdk-commands/package-lock.json @@ -15,7 +15,7 @@ "@dcl/inspector": "file:../inspector", "@dcl/linker-dapp": "^0.12.0", "@dcl/mini-comms": "1.0.1-20230216163137.commit-a4c75be", - "@dcl/protocol": "1.0.0-9959547690.commit-67e81c4", + "@dcl/protocol": "1.0.0-10043247792.commit-428d1eb", "@dcl/quests-client": "^1.0.3", "@dcl/quests-manager": "^0.1.4", "@dcl/rpc": "^1.1.1", @@ -238,9 +238,9 @@ } }, "node_modules/@dcl/protocol": { - "version": "1.0.0-9959547690.commit-67e81c4", - "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-9959547690.commit-67e81c4.tgz", - "integrity": "sha512-o6D3wiYOgKwsHn6Wvv7vj5dnzmkMtJIZad3nOcoAbushmuvpRHbC0CirwkjtFanrqMlBrFq/Xv4X9PQvvHY+HA==", + "version": "1.0.0-10043247792.commit-428d1eb", + "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-10043247792.commit-428d1eb.tgz", + "integrity": "sha512-rHXQhXBJawMpPEZACp2fdHEK4ZhKw3xJaVz3IpzHdrxYWdPThKf2pUkYZZ/2iQ248GrlDRM9G7ou7lOk8SwOzw==", "dependencies": { "@dcl/ts-proto": "1.154.0" } @@ -3227,9 +3227,9 @@ } }, "@dcl/protocol": { - "version": "1.0.0-9959547690.commit-67e81c4", - "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-9959547690.commit-67e81c4.tgz", - "integrity": "sha512-o6D3wiYOgKwsHn6Wvv7vj5dnzmkMtJIZad3nOcoAbushmuvpRHbC0CirwkjtFanrqMlBrFq/Xv4X9PQvvHY+HA==", + "version": "1.0.0-10043247792.commit-428d1eb", + "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-10043247792.commit-428d1eb.tgz", + "integrity": "sha512-rHXQhXBJawMpPEZACp2fdHEK4ZhKw3xJaVz3IpzHdrxYWdPThKf2pUkYZZ/2iQ248GrlDRM9G7ou7lOk8SwOzw==", "requires": { "@dcl/ts-proto": "1.154.0" } diff --git a/packages/@dcl/sdk-commands/package.json b/packages/@dcl/sdk-commands/package.json index 7303adc74..8e6129163 100644 --- a/packages/@dcl/sdk-commands/package.json +++ b/packages/@dcl/sdk-commands/package.json @@ -13,7 +13,7 @@ "@dcl/inspector": "file:../inspector", "@dcl/linker-dapp": "^0.12.0", "@dcl/mini-comms": "1.0.1-20230216163137.commit-a4c75be", - "@dcl/protocol": "1.0.0-9959547690.commit-67e81c4", + "@dcl/protocol": "1.0.0-10043247792.commit-428d1eb", "@dcl/quests-client": "^1.0.3", "@dcl/quests-manager": "^0.1.4", "@dcl/rpc": "^1.1.1", diff --git a/packages/@dcl/sdk-commands/src/commands/start/data-layer/rpc.ts b/packages/@dcl/sdk-commands/src/commands/start/data-layer/rpc.ts index 60d1af8db..138afb7e2 100644 --- a/packages/@dcl/sdk-commands/src/commands/start/data-layer/rpc.ts +++ b/packages/@dcl/sdk-commands/src/commands/start/data-layer/rpc.ts @@ -17,6 +17,7 @@ export async function createDataLayer(components: Pick({ logger: components.logger }) rpcServer.setHandler(async function rpcHandler(serverPort: RpcServerPort) { diff --git a/packages/@dcl/sdk-commands/src/commands/start/explorer-alpha.ts b/packages/@dcl/sdk-commands/src/commands/start/explorer-alpha.ts new file mode 100644 index 000000000..eb9d1f471 --- /dev/null +++ b/packages/@dcl/sdk-commands/src/commands/start/explorer-alpha.ts @@ -0,0 +1,33 @@ +import { CliComponents } from '../../components' + +const isWindows = /^win/.test(process.platform) + +export async function runExplorerAlpha( + components: CliComponents, + opts: { cwd: string; realm: string; baseCoords: { x: number; y: number } } +) { + const { cwd, realm, baseCoords } = opts + + if (await runApp(components, { cwd, realm, baseCoords })) { + return + } + + components.logger.log('Please download & install the Decentraland Desktop Client: https://dcl.gg/explorer\n\n') +} + +async function runApp( + components: CliComponents, + { cwd, realm, baseCoords }: { cwd: string; realm: string; baseCoords: { x: number; y: number } } +) { + const cmd = isWindows ? 'start' : 'open' + try { + const params = `realm=${realm}&position=${baseCoords.x},${baseCoords.y}&local-scene=true` + const app = `decentraland://"${params}"` + await components.spawner.exec(cwd, cmd, [app], { silent: true }) + components.logger.info(`Desktop client: decentraland://${params}\n`) + return true + } catch (e: any) { + components.logger.error('Decentraland Desktop Client failed with: ', e.message) + return false + } +} diff --git a/packages/@dcl/sdk-commands/src/commands/start/index.ts b/packages/@dcl/sdk-commands/src/commands/start/index.ts index ac8d8c058..ea9371b92 100644 --- a/packages/@dcl/sdk-commands/src/commands/start/index.ts +++ b/packages/@dcl/sdk-commands/src/commands/start/index.ts @@ -26,6 +26,7 @@ import { getValidWorkspace } from '../../logic/workspace-validations' import { printCurrentProjectStarting, printProgressInfo, printWarning } from '../../logic/beautiful-logs' import { Result } from 'arg' import { startValidations } from '../../logic/project-validations' +import { runExplorerAlpha } from './explorer-alpha' interface Options { args: Result @@ -49,7 +50,8 @@ export const args = declareArgs({ '-w': '--no-watch', '--skip-build': Boolean, '--desktop-client': Boolean, - '--data-layer': Boolean + '--data-layer': Boolean, + '--explorer-alpha': Boolean }) export async function help(options: Options) { @@ -90,6 +92,7 @@ export async function main(options: Options) { const watch = !options.args['--no-watch'] const withDataLayer = options.args['--data-layer'] const enableWeb3 = options.args['--web3'] + const explorerAlpha = options.args['--explorer-alpha'] let hasSmartWearable = false @@ -135,7 +138,7 @@ export async function main(options: Options) { }) const logs = await createConsoleLogComponent({}) const ws = await createWsComponent({ logs }) - const server = await createServerComponent({ config, logs, ws: ws.ws }, { cors: {} }) + const server = await createServerComponent({ config, ws: ws.ws, logs }, { cors: {} }) const rooms = await createRoomsComponent({ metrics, logs, @@ -170,7 +173,7 @@ export async function main(options: Options) { await wireRouter(components, workspace, dataLayer) if (watch) { for (const project of workspace.projects) { - await wireFileWatcherToWebSockets(components, project.workingDirectory, project.kind) + await wireFileWatcherToWebSockets(components, project.workingDirectory, project.kind, !!explorerAlpha) } } await startComponents() @@ -179,7 +182,9 @@ export async function main(options: Options) { const availableURLs: string[] = [] printProgressInfo(options.components.logger, 'Preview server is now running!') - components.logger.log('Available on:\n') + if (!explorerAlpha) { + components.logger.log('Available on:\n') + } Object.keys(networkInterfaces).forEach((dev) => { ;(networkInterfaces[dev] || []).forEach((details) => { @@ -203,8 +208,10 @@ export async function main(options: Options) { return a.toLowerCase().includes('localhost') || a.includes('127.0.0.1') || a.includes('0.0.0.0') ? -1 : 1 }) - for (const addr of sortedURLs) { - components.logger.log(` ${addr}`) + if (!explorerAlpha) { + for (const addr of sortedURLs) { + components.logger.log(` ${addr}`) + } } if (options.args['--desktop-client']) { @@ -216,11 +223,18 @@ export async function main(options: Options) { } } - components.logger.log('\n Details:\n') + if (!explorerAlpha) { + components.logger.log('\n Details:\n') + } components.logger.log('\nPress CTRL+C to exit\n') + if (explorerAlpha) { + const realm = new URL(sortedURLs[0]).origin + await runExplorerAlpha(components, { cwd: workingDirectory, realm, baseCoords }) + } + // Open preferably localhost/127.0.0.1 - if (openBrowser && sortedURLs.length && !options.args['--desktop-client']) { + if (!explorerAlpha && openBrowser && sortedURLs.length && !options.args['--desktop-client']) { try { await open(sortedURLs[0]) } catch (_) { diff --git a/packages/@dcl/sdk-commands/src/commands/start/server/file-watch-notifier.ts b/packages/@dcl/sdk-commands/src/commands/start/server/file-watch-notifier.ts index 47baa2ad5..8a120758a 100644 --- a/packages/@dcl/sdk-commands/src/commands/start/server/file-watch-notifier.ts +++ b/packages/@dcl/sdk-commands/src/commands/start/server/file-watch-notifier.ts @@ -7,6 +7,10 @@ import { PreviewComponents } from '../types' import { sceneUpdateClients } from './routes' import { ProjectUnion } from '../../../logic/project-validations' import { b64HashingFunction } from '../../../logic/project-files' +import { + WsSceneMessage, + UpdateModelType +} from '@dcl/protocol/out-js/decentraland/sdk/development/local_development.gen' function debounce void>(callback: T, delay: number) { let debounceTimer: NodeJS.Timeout @@ -24,29 +28,81 @@ function debounce void>(callback: T, delay: number export async function wireFileWatcherToWebSockets( components: Pick, projectRoot: string, - projectKind: ProjectUnion['kind'] + projectKind: ProjectUnion['kind'], + desktopClient: boolean ) { const ignored = await getDCLIgnorePatterns(components, projectRoot) - + const sceneId = b64HashingFunction(projectRoot) chokidar .watch(path.resolve(projectRoot), { + atomic: false, ignored, ignoreInitial: false, cwd: projectRoot }) + .on('unlink', (_: unknown, file: string) => { + if (desktopClient) { + return removeModel(sceneId, file) + } + }) .on( 'all', - debounce(async (_, _file) => { - // TODO: accumulate changes in an array and debounce - return updateScene(projectRoot, sceneUpdateClients, projectKind) + debounce(async (a, file) => { + if (desktopClient) { + updateScene(sceneId, file) + } + return __LEGACY__updateScene(projectRoot, sceneUpdateClients, projectKind) }, 500) ) } -/* - * IMPORTANT: this is a legacy protocol and needs to be revisited for SDK7 +function isGLTFModel(file: string) { + if (!file) return false + return file.toLowerCase().endsWith('.glb') || file.toLowerCase().endsWith('.gltf') +} + +function updateScene(sceneId: string, file: string) { + let message: WsSceneMessage['message'] + if (isGLTFModel(file)) { + message = { + $case: 'updateModel', + updateModel: { hash: b64HashingFunction(file), sceneId, src: file, type: UpdateModelType.UMT_CHANGE } + } + } else { + message = { + $case: 'updateScene', + updateScene: { sceneId } + } + } + sendSceneMessage({ message }) +} + +function removeModel(sceneId: string, file: string) { + if (isGLTFModel(file)) { + const sceneMessage: WsSceneMessage = { + message: { + $case: 'updateModel', + updateModel: { sceneId, src: file, hash: b64HashingFunction(file), type: UpdateModelType.UMT_REMOVE } + } + } + + sendSceneMessage(sceneMessage) + } +} + +function sendSceneMessage(sceneMessage: WsSceneMessage) { + const message = WsSceneMessage.encode(sceneMessage).finish() + for (const client of sceneUpdateClients) { + if (client.readyState === WebSocket.OPEN) { + client.send(message, { binary: true }) + } + } +} + +/** + * @deprecated old explorer (kernel) */ -function updateScene(dir: string, clients: Set, projectKind: ProjectUnion['kind']): void { +export function __LEGACY__updateScene(dir: string, clients: Set, projectKind: ProjectUnion['kind']): void { for (const client of clients) { if (client.readyState === WebSocket.OPEN) { const message: sdk.SceneUpdate = { @@ -54,8 +110,9 @@ function updateScene(dir: string, clients: Set, projectKind: ProjectU payload: { sceneId: b64HashingFunction(dir), sceneType: projectKind } } - client.send(sdk.UPDATE) - client.send(JSON.stringify(message)) + // Old explorer + client.send(sdk.UPDATE, { binary: false }) + client.send(JSON.stringify(message), { binary: false }) } } } diff --git a/packages/@dcl/sdk-commands/src/commands/start/server/ws.ts b/packages/@dcl/sdk-commands/src/commands/start/server/ws.ts index c82fd90eb..a445b7d33 100644 --- a/packages/@dcl/sdk-commands/src/commands/start/server/ws.ts +++ b/packages/@dcl/sdk-commands/src/commands/start/server/ws.ts @@ -12,7 +12,6 @@ export type WebSocketComponent = IBaseComponent & { */ export async function createWsComponent(_: Pick): Promise { const ws = new WebSocketServer({ noServer: true }) - async function stop() { ws.close() } diff --git a/packages/@dcl/sdk-commands/src/logic/bundle.ts b/packages/@dcl/sdk-commands/src/logic/bundle.ts index 6ee539528..01654551f 100644 --- a/packages/@dcl/sdk-commands/src/logic/bundle.ts +++ b/packages/@dcl/sdk-commands/src/logic/bundle.ts @@ -291,7 +291,6 @@ function compositeLoader(components: BundleComponents, options: SingleProjectOpt 'Some composites are not included because of errors while compiling them. There can be unexpected behavior in the scene, check the errors and try to fix them.' ) } else if (!lastBuiltSuccessful) { - components.logger.log('Composites built without errors.') } lastBuiltSuccessful = !data.withErrors }