dewctl 0.6.0 → 0.6.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.
@@ -62,8 +62,9 @@ A new look usually means changing the first three together.
62
62
  ([colors](https://alpha.dewdrop.world/docs/renderer#colors)).
63
63
  - **Describe what the camera sees, in the style's words:** "the back of an owl's head" behind a character,
64
64
  "a plasticine tree". Use one description for each kind of object.
65
- - **Keep color words in step with the colors.** "Terracotta" on a pale roof came out red, and "pale cream wall"
66
- came out white on a dark wall. Name the material without its lightness
65
+ - **Keep color words in step with the colors.** A color or lightness word overrides the mesh's color: a pale roof
66
+ described as "terracotta" turns red, and a dark wall described as "pale cream" turns white. Name the material
67
+ without its lightness
67
68
  ([descriptions](https://alpha.dewdrop.world/docs/renderer#descriptions)).
68
69
  - A group's description reaches every mesh under it that has none of its own; `null` gives none, and a mesh's
69
70
  `name` is never used ([scene graph](https://alpha.dewdrop.world/docs/descriptions)).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dewctl",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Build and publish three.js games on Dewdrop.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/client.js CHANGED
@@ -69,13 +69,14 @@ export class Client {
69
69
  if(result.release!==bundle.id)throw new Error('Dewdrop stored a different release than was uploaded, so nothing was changed. Try again.');
70
70
  return result;
71
71
  }
72
- activate(game,release,signal){return this.point(game,'dev',release,signal);}
72
+ activate(game,release,signal,started){return this.point(game,'dev',release,signal,started);}
73
73
  stop(game,signal){return this.point(game,'dev',null,signal);}
74
74
  publish(game,release,signal){return this.point(game,'live',release,signal);}
75
75
  // Points a version at a release, then follows the game until that version is ready, fails, or somebody points it
76
- // elsewhere. The PUT answers with the game, so it is the first look.
77
- async point(game,version,release,signal) {
76
+ // elsewhere. The PUT answers with the game, so it is the first look, handed to `started` before the wait.
77
+ async point(game,version,release,signal,started) {
78
78
  let state=await this.api(`/v1/games/${game}/${version}`,{method:'PUT',body:{release},signal});
79
+ started?.(state);
79
80
  if(release===null&&version==='live')return state;
80
81
  const doing=release===null?'Stopping the dev version':version==='dev'?'Starting the dev version':'Publishing',deadline=Date.now()+this.timeoutMs;
81
82
  for(;;) {
package/src/main.js CHANGED
@@ -189,8 +189,8 @@ async function main() {
189
189
  }
190
190
  if(flags.release){
191
191
  const release=await releaseId(client,game,flags.release);
192
- const state=await client.activate(game,release,signal);
193
- console.log(`Playing ${release.slice(0,12)} at ${devPlayUrl(state)}`);return;
192
+ await client.activate(game,release,signal,state=>console.log(`Starting ${release.slice(0,12)} at ${devPlayUrl(state)}`));
193
+ console.log('Ready to play.');return;
194
194
  }
195
195
  if(flags.watch)await watch(project,client,{signal,reread:()=>readProject(project.root)});
196
196
  else if((await deploy(project,client,{signal})).changed)throw new Error(`Files changed during the build, so nothing was uploaded. Run ${RUN} dev again, or ${RUN} dev --watch to rebuild on every save.`);
package/src/project.js CHANGED
@@ -166,7 +166,7 @@ const SDK_RANGE='^0.6.0';
166
166
  const CLI_RANGE=`^${JSON.parse(readFileSync(new URL('../package.json',import.meta.url),'utf8')).version}`;
167
167
  // The games a new one can start from: Blank, which ships with this CLI, and the starter games in the public
168
168
  // starter-templates repository, a folder each, at the commit this release pins.
169
- const STARTERS={repo:'DewdropLabs/starter-templates',commit:'4247a60d29f5477b94b498fcd31a4c3c0e873cc0'};
169
+ const STARTERS={repo:'DewdropLabs/starter-templates',commit:'8d7743c1f13ca979daf3afe92063ee12a396e52e'};
170
170
  const TEMPLATES={
171
171
  blank:['Blank','a cube and a style prompt, the smallest game'],
172
172
  'golden-glide':['Golden Glide','flight over golden-hour countryside, in gouache'],
@@ -180,11 +180,14 @@ const EXAMPLES=fileURLToPath(new URL('../examples/',import.meta.url)),BLANK=join
180
180
  export async function chooseTemplate(input=process.stdin, output=process.stdout) {
181
181
  const ids=Object.keys(TEMPLATES),ask=`Choose 1–${ids.length} [1]: `;
182
182
  output.write(`Start from:\n${ids.map((id,i)=>` ${i+1} ${TEMPLATES[id][0].padEnd(14)}${TEMPLATES[id][1]}`).join('\n')}\n${ask}`);
183
- for await (const line of createInterface({input})) {
184
- const answer=line.trim()||'1',id=/^\d$/.test(answer)&&ids[answer-1];
185
- if(id)return id;
186
- output.write(ask);
187
- }
183
+ // Closing the reader leaves the terminal's input open, which would keep the CLI running once init is done.
184
+ try {
185
+ for await (const line of createInterface({input})) {
186
+ const answer=line.trim()||'1',id=/^\d$/.test(answer)&&ids[answer-1];
187
+ if(id)return id;
188
+ output.write(ask);
189
+ }
190
+ } finally { input.pause(); }
188
191
  throw new Error('No game was chosen to start from.');
189
192
  }
190
193
  // A starter game's files, from the repository's tarball at the pinned commit (or the one DEWDROP_STARTERS names, for
package/src/watch.js CHANGED
@@ -22,8 +22,8 @@ export async function deploy(project,client,{signal,log=console.log}={}) {
22
22
  const parts=Math.max(1,Math.ceil(bundle.body.length/PART_BYTES));
23
23
  log(`Uploading ${bundle.files} file${bundle.files===1?'':'s'} (${size(bundle.bytes)})${parts>1?` in ${parts} parts`:''}…`);
24
24
  await client.upload(project.game,bundle,signal);
25
- const game=await client.activate(project.game,bundle.id,signal);
26
- log(`Playing ${bundle.id.slice(0,12)} at ${devPlayUrl(game)}`);
25
+ await client.activate(project.game,bundle.id,signal,game=>log(`Starting ${bundle.id.slice(0,12)} at ${devPlayUrl(game)}`));
26
+ log('Ready to play.');
27
27
  return {changed:false};
28
28
  }
29
29