profile
viewpoint
Jamie Kyle jamiebuilds Eventbrite Oakland, CA https://jamie.build/ Code Ruins Everything Around Me

push eventjamiebuilds/react-jeff

Jamie Kyle

commit sha 9bfed4acfe2e6bbe02edd2761e7d3bc19b9c66aa

1.2.1

view details

push time in 4 days

created tagjamiebuilds/react-jeff

tagv1.2.1

A Good Form Library

created time in 4 days

push eventjamiebuilds/react-jeff

Rafau

commit sha 11db0cf595c1327a88af0682655505a7354c316b

update valueRef in reset function (#3) Hi, `valueRef` should be updated on filed reset. Thank you

view details

push time in 4 days

PR merged jamiebuilds/react-jeff

update valueRef in reset function

Hi,

valueRef should be updated on field reset.

Thank you

+1 -0

0 comment

1 changed file

RafalFilipek

pr closed time in 4 days

push eventjamiebuilds/the-perfect-test-framework

Jamie Kyle

commit sha 5592f585543964473a7349f6bc4c9b5d4c070397

replace t.extendTimeout() with t.timeout()

view details

push time in 4 days

pull request commentguybedford/proposal-pkg-targets

Add Jamie Kyle to contributors

+1

guybedford

comment created time in 10 days

issue commentjamiebuilds/react-performance-observer

getting 3 console.logs

Hm, I'm not sure. Are those logging in the same run?

iqbal125

comment created time in 10 days

PR opened parcel-bundler/parcel

Link to reasoning behind plugin name validation

Figured it would be good to keep this reasoning in the codebase so if someone comes back to it years from now they'll know why it was done this way.

+2 -0

0 comment

1 changed file

pr created time in 10 days

create barnchparcel-bundler/parcel

branch : jamiebuilds-patch-1

created branch time in 10 days

issue commentparcel-bundler/parcel

Parcel 2: Supports in-repository plugins

I understand exactly why this is desired. But this was actually an intentional design decision.

To explain why, let me explain what happened with the Babel ecosystem...

When we designed the Babel plugin API, all we really cared about was an entry point to the plugin, specifying a plugin was literally just the node module resolution API.

However there were two big problems with this:

  1. The highly dynamic nature of how plugins/presets get resolved in Babel makes it effectively impossible to ever do caching well in any sort of automatic way.
  2. Because people could put plugins wherever they wanted, 99% of the Babel ecosystem is actually not in packages. The vast majority of Babel plugins are actually internal to companies sitting in random folders, or buried in other tools like Jest.

Both of these were really bad outcomes for Babel. Performance is made significantly worse by not having great caching, and not having plugins in packages has cause the ecosystem to miss out from a lot of great contributions. Not having plugins in packages has also caused a lot of people to have really messy build systems around Babel that make it hard to upgrade over time, primarily because they aren't versioned.

In Parcel we have a chance to do things differently. We want to learn from past mistakes in tools like Babel (which are partially my fault).

So in Parcel we've decided (so far) that plugin specifiers = names of versioned packages because:

  1. It makes cache invalidation significantly easier -- We can rely on the package version unless it is symlinked in which case we also know that it's being worked on and we can watch it
  2. It helps grow the Parcel ecosystem -- By forcing everyone to create packages, they are only 1 step away from open sourcing it and contributing back.
  3. It helps keep our user's codebases cleaner and more maintainable over time -- They can version their Parcel plugin alongside Parcel versions and upgrade their codebases more incrementally.

I know that this comes at the cost of forcing plugin authors to learn what packages even are or how to develop packages. But I think going through that process will help them build better plugins (and gain transferable skills in the process).

It's not the most convenient thing we could do, but Parcel is trying to clean up a lot of what the JavaScript bundler toolchain has been doing the last several years. The good news is that these sorts of restrictions are easy to relax later, but if we didn't start with them we wouldn't be able to add them in later.

arcanis

comment created time in 10 days

issue commentguybedford/proposal-pkg-entries

Parcel 2's package.json#targets

would you be ok for me to list you as contributors?

Sure

If we allow names to have precedence associated with them in the resolver or spec, then combined precedence if we also introduce | might be defined by the specificity level (number of |), followed by the precedence ordering over any similar condition grouping. That seems like it could be well-defined actually.

Then the default precedence is probably something like (where each row is equal precedence, and environments / tools would only enable the ones that apply):

electron, react-native
parcel, jspm, webpack, rollup (do we want these?)
node, browser
worker, chrome-extension (do we want these?)
esmodule, wasm
main

I think this is the major divergence of what we're trying to do here.

Consider all the different things those field names are accounting for:

  1. JavaScript engine (browser, node)
  2. JavaScript global env/available apis (browser, node, electron, react-native, worker, chrome-extension)
  3. Tool resolving the package (parcel, jspm, webpack, rollup)
  4. JavaScript version/feature support (main, module, esmodule)

If we explode that out into a matrix of all the different combinations of "Browser/Node/Electron environment that supports/doesn't support modules and ES5/ES2015/ES2016"

Then you get into the problem of what do those mean over time. If we're using a very generic label like "browser" we could say that means Chrome 75, Safari 12, etc. But then 5 years down the line no one cares about those versions anymore, what do we do? Change the definition? Now every package using the old definition is out of date.

My opinion is that we should throw in the towel trying to make package.json entry fields make any sense, and we should focus on giving tools better metadata to make a more informed decision based on what the package was actually built for.

Then it doesn't matter what fields a package author defines. They could have a package.json#hissingbubblegumslide field and describe it in package.json#targets and it would work forever and no one but the package author would ever care.

Taking that into consideration, I would also like a central place for defining what different field names in package.json#targets means.

{
  "targets": {
    "hissingbubblegumslide": {
      "browsers": ["Chrome >= 75", ...], // https://package-json-target-types.org/spec#browsers
      "modules": "esm", // https://package-json-target-types.org/spec#modules
      "node": ">=4.0.0", // https://package-json-target-types.org/spec#node
      "electron": "..." // https://package-json-target-types.org/spec#electron
      ...
    }
  }
}
jamiebuilds

comment created time in 11 days

issue commentparcel-bundler/parcel

RFC: Rich, actionable errors in Parcel 2

I don't think @sebmck will mind me sharing this gist he made for me awhile ago...

This is the type interface for diagnostics in Rome https://gist.github.com/sebmck/13a02b60095767b978e8124c326626f3

gorakong

comment created time in 15 days

push eventjamiebuilds/aria-data

Indrek Paas

commit sha 0c3b9346eeda4dc17ac4d112af4dd4d894da7c77

Improve '(default)' string matching (#2) * Improve '(default)' string matching * Trigger rebuild

view details

push time in 17 days

PR merged jamiebuilds/aria-data

Improve '(default)' string matching

Unfortunately the official spec document is little bit inconsistent with presenting attribute values. This PR fixes a single occurrence of such issue.

+2 -2

0 comment

2 changed files

indrekpaas

pr closed time in 17 days

startedytdl-org/youtube-dl

started time in 25 days

started1995parham/github-do-not-ban-us

started time in 25 days

issue commentguybedford/proposal-pkg-entries

Parcel 2's package.json#targets

I guess I'm trying to define the behaviour here for when there is no targets present, and then to try to work out how targets could refine or additively apply.

Right now with multiple entry points defined in a package.json priority is determined by the resolver rather than the package itself (i.e. the mainFields: ["browser", "module", "main"] config option in Webpack's resolver I mentioned before).

package.json#targets is in part trying to solve that hard-coded behavior so the resolver can make an informed decision on a package-by-package basis as described by the individual packages.

Since we were talking about having the names be mirrored in package.json#entries/targets/exports I think it makes sense to continue to use the "mainFields", ordered list of field names resolution, that exists in the ecosystem today.

Then we can come back later with package.json#targets and solve the problem without having to backwards support the ordered objects of exports.

resolvePackageEntry(pkg, { mainFields: ["browser", "module", "main"])
{
  "main": "...",
  "module": "...",
  "browser": "...", // selected because "browser" was first in array
  "exports": {
    "./feature": {
      "main": "...",
      "module": "..." // selected because "browser" doesn't exist and "module" was second in array
    }
  }
}

jamiebuilds

comment created time in 25 days

issue commentguybedford/proposal-pkg-entries

Parcel 2's package.json#targets

because they are selected in object order

What's the reasoning for selecting them in that order. Not that I'm opposed to adding order to keys in JSON objects (That's a huge part of the design of .parcelrc). But it seems odd that:

  1. package.json#exports would behave differently from package.json#<mainFields...>
  2. package.json#exports wouldn't use the same information that is being provided in package.json#targets (assuming the functionality of package.json#targets was added)

(is the expectation that "targets" would be supported for installed packages in node_modules?)

Yes, it's also part of our strategy to know which installed packages need additional transpiling and which ones we're okay just using. If we can't find an entry point to a module that meets our requirements, we'll select one that is "closest" and compile it down further. (This is a big problem within existing tools today, I've seen a lot of not-enough-transpiled code end up in production that came from node_modules)

jamiebuilds

comment created time in a month

issue commentguybedford/proposal-pkg-entries

Parcel 2's package.json#targets

the conditions get checked in object order from top to bottom. The first truthy environment is then selected. So if none match, we get the "default" as the always-truthy fallback.

Okay, in that case I would question that "main" isn't a better name for the "always truthy" case. It's somewhat already understood to have that meaning, and I think it's more important to align with package.json#main than to use a more precise term (However much you can really argue that "default" is a precise term).

But going along with "default" I would still expect entries/targets/exports[*] to have a "main" in addition to "default" (or at least the ability to have both). In which case, I think I could make a more compelling argument to have a top-level package.json#defaultEntryField (or whatever name suits best):

{
  "main": "...", // is default
  "module": "...",
  "browser": "...",
  "defaultEntryField": "main",
  "targets": {
    "main": {...}, // is default
    "module": {...},
    "browser": {...},
  },
  "exports": {
    "./feature": {
      "main": "...", // is default
      "module": "...",
      "browser": "..."
    }
  }
}
jamiebuilds

comment created time in a month

issue commentguybedford/proposal-pkg-entries

Parcel 2's package.json#targets

The major feature I want though really is to be able to share the meaning of these names, just like you have in targets, with both aliases and exports

I absolutely agree with that. I much prefer the separate package.json#targets/exports/aliases fields such that you can have any combination of them without having all of them in the form of a deeply nested object (which would also be harder to memorize or teach).

In terms of having a "default" I think we need to consider carefully what we're implying. Because in terms of the "default" package.json#"entry" you can't really say there is one, because it entirely depends on the context you are requesting it from.

{
  "name": "package-name",
  "main": "dist/main/index.js", // "main" is the default if you are in a commonjs env (generally falling back to fs resolution, or another field if you've configured a bundler to do so)
  "module": "dist/module/index.js", // "module" is the default if you are in a esm env (generally falling back to "main")
  "browser": "dist/browser/index.js" // "browser" is the default if you are requesting for a browser bundle. (generally falling back to either "module" or "main")
}

However, you certainly could have a "defaults" in terms of the configuration for all of your entry fields.

{
  "name": "package-name",
  "main": "dist/main/index.js",
  "module": "dist/module/index.js",
  "browser": "dist/browser/index.js",
  "targets": {
    "default": {...}, // `package.json#main/module` uses this config (because they aren't configured separately)
    "browser": {...} // But `package.json#browser` uses this config
  }
}

However, in terms of this "default" configuration, I think we actually have a better option today: top-level fields

{
  "name": "package-name",
  "main": "dist/main/index.js",
  "module": "dist/module/index.js",
  "browser": "dist/browser/index.js",
  "engines": { "node": ">=4.0.0" }, // default targets config
  "browserslist": "...", // default targets config
  "targets": {
    "main": {
      // "node" -- defaults to `package.json#engines.node`
      "browsers": false // override to turn off default
    },
    "module": {
      "node": ">=12.0.0", // override to new value
      "browsers": "..." // override to new value
    },
    "browser": {
      "node": false // override to turn off default
      // "browsers" -- defaults to `package.json#browserslist
    }
  }
}

Counter Argument: People may be confused that they have to set "node": false on the "browser" field, thinking that the name implies more.

Alternative "defaults":

{
  "targets": {
    "defaults": {
      "node": ">4"
      "browsers": "..."
    },
    "main": {...},
    "module": {...},
    "browser": {...}
  }
}
jamiebuilds

comment created time in a month

startedmicrosoft/node-jsonc-parser

started time in a month

issue commentguybedford/proposal-pkg-entries

Parcel 2's package.json#targets

One thing I'm worried about is that if "entries" or "targets" didn't align with the existing ecosystem around top-level package.json fields, it will confuse people. In my research, I found a lot of tools that expect a single key name for the package.json#"entry", Webpack for example has the "mainFields": ["browser", "module", "main"] configuration.

Using your example before, I think it's more likely that people will write this (in order to remain compatible with the existing ecosystem):

{
  "name": "package-name",
  "main": "dist/main/index.js",
  "module": "dist/module/index.js",
  "browser": "dist/browser/index.js",
  "entries": {
    "module": "dist/module/index.js",
    "browser": "dist/browser/index.js",
    "default": "dist/main/index.js"
  },
  "targets": {
    "default": {...},
    "module": {...},
    "browser": {...}
  }
}

At which point it's kinda confusing that "default" and "main" effectively mean the same thing.

But if you do align the key names, then it also feels like a lot of extra work that users won't necessarily understand what they are getting from it:

{
  "name": "package-name",
  "main": "dist/main/index.js",
  "module": "dist/module/index.js",
  "browser": "dist/browser/index.js",
  "entries": {
    "module": "dist/module/index.js",
    "browser": "dist/browser/index.js",
    "default": "dist/main/index.js"
  },
  "targets": {
    "default": {...},
    "module": {...},
    "browser": {...}
  }
}

So while I think that these proposal can definitely be introduced separately without conflicting with one another (Yes they are both mutually additive imo). I think we should try for something more unified so that users 1. Don't feel like they are being forced to do a ton of extra work and 2. Understand everything that they are getting from any additional work they are putting in.

jamiebuilds

comment created time in a month

issue openednodejs/modules

Add @jamiebuilds and @devongovett as observers

We've been working on the Parcel bundler and writing our own specifications around module resolution. We met with @guybedford today to talk about how some of our work aligns with the work of the node modules committee and work from other bundlers, and he suggested that we attend the next modules meeting.

created time in a month

issue openedguybedford/proposal-pkg-entries

Parcel 2's package.json#targets

Opening this issue after our discussion on how to align this proposal and the work that Parcel is doing to specify what Parcel 2 has proposed with package.json#targets.

At a high-level package.json#targets looks like this:

{
  "name": "package-name",
  "main": "dist/main/index.js",
  "module": "dist/module/index.js",
  "browser": "dist/browser/index.js",
  "targets": {
    "main": {
      "node": ["^4.0.0"]
    },
    "module": {
      "node": ["^8.0.0"]
    },
    "browser": {
      "browsers": ["> 1%", "not dead"]
    }
  }
}

For background, our motivations in this design were to solve for the following problems:

  • How do we decide which package.json fields are entry points to the package?
  • How do we know what a package.json entry field actually means (in terms of the environment it is supposed to be executed in)?
  • How do we align with the existing fields to describe the targeted environment for a package?

We also wanted to make sure that we designed something that:

  • Didn't change anything about the existing ecosystem
  • Didn't ask too much of the package author
  • Wouldn't conflict with existing toolchains

Basically what we ended up designing was a way of storing metadata about what existing entry fields existed and what they meant to the package author. We designed package.json#targets to not care when package authors added new package.json entry fields, and not to care when the ecosystem defined a new type of environment that an entry point could be targeting.

For starters, if you wanted to know what entry fields existed in package.json you could do keys(package.json#targets):

{
  // ...tons of other fields that may or may not be entries...
  "targets": {
    "main": {...},
    "module": {...},
    "browser": {...}
  }
}

This keeps us compatible with tools that really want the entry fields to be in the top-level of the package.json object, and we weren't replacing them at all, just describing them.

The package.json#targets values then start describing the environment they are intending to support. So from the context in which I am requesting the entry point for a package, I can say "I want X package for Y environment"

{
  "targets": {
    "entry-a": {
      "environment-x": true
    },
    "entry-b": {
      "environment-y": true
    }
  }
}

For the above package.json#targets, if I'm looking for an entry that can target "environment-y" I can easily figure out that entry-b is the only entry that supports that environment.

This is not intended to be a strictly defined system, it's meant to support whatever the ecosystem may come up with next-- Just tell us what it is and we'll do our best to make it work from the tooling side.

There is more information about this proposal in the Parcel 2 RFC

created time in a month

issue commentjamiebuilds/react-performance-observer

getting 3 console.logs

Are you sure your app isn't rendering 3 separate times?

iqbal125

comment created time in a month

push eventjamiebuilds/ci-parallel-vars

THAC0

commit sha 97b9ea8dcdef289b4f2263d959d216b7f0876a65

update readme to include GitLab and Semaphore (#4)

view details

push time in a month

PR merged jamiebuilds/ci-parallel-vars

update readme to include GitLab and Semaphore

Hi, I was originally going to add GitLab env vars but then I realised they're the same as the Travis & Knapsack vars, so I've just updated the readme instead.

Also the Semaphore vars are included in index.js, but weren't in the readme so I've added them too.

Ta

+6 -3

0 comment

2 changed files

gunjam

pr closed time in a month

push eventjamiebuilds/jamie.build

Jamie Kyle

commit sha 71fe608d376f26564c4096224d63a67b828eb350

Update index.html

view details

push time in a month

push eventboltpkg/bolt

Jamie Kyle

commit sha 4a61029b5456d7080ca2b44353ab586cb8a31fd7

0.23.5

view details

push time in a month

created tagboltpkg/bolt

tagv0.23.5

⚡️ Super-powered JavaScript project management

created time in a month

push eventboltpkg/bolt

Kyle Welch

commit sha cb41cd0572a037584b3822a7a7cf73e2dce80310

Updated to skip workspaces that are missing a package.json (#235) * Updates to skip workspaces that don't have a package.json defined * update tests and flow to handle maybe Config * revert a bunch of things and throw error instead of return null * more reverts * Update getPackages to handle BoltError

view details

push time in a month

PR merged boltpkg/bolt

Updated to skip workspaces that are missing a package.json

Instead of sending a message about an empty workspace, skip it entirely.

This avoids having to remove the directory and re-run the command.

I added a test that covers this case as well.

+38 -2

1 comment

6 changed files

kwelch

pr closed time in a month

startedjamiebuilds/bundlephobia-compare

started time in a month

push eventjamiebuilds/bundlephobia-compare

Jamie Kyle

commit sha a7bf048ce97cc263c88d2c1dce543f88d5678aed

sync with url

view details

push time in a month

push eventjamiebuilds/bundlephobia-compare

Jamie Kyle

commit sha dc896784f0ffdf191886349e042c69be2be2e629

add build script

view details

push time in a month

create barnchjamiebuilds/bundlephobia-compare

branch : master

created branch time in a month

created repositoryjamiebuilds/bundlephobia-compare

created time in a month

push eventjamiebuilds/react-jeff

Jamie Kyle

commit sha 13b8dc96d37183b14c1c07796cbbed9922f32189

Update README.md

view details

push time in a month

push eventjamiebuilds/react-jeff

Jamie Kyle

commit sha 0f114a6ec8aec68f5b30db32e2f54e9c928aff63

Update README.md (#2)

view details

push time in a month

PR merged jamiebuilds/react-jeff

Update README.md
+11 -2

0 comment

1 changed file

jamiekyle-eb

pr closed time in a month

push eventjamiebuilds/react-loadable

Drew McMillan

commit sha fd8a77fcc2a4a80de837dda2d6c15a85cc3fdea5

Add BBC News to Readme (#192)

view details

push time in a month

issue commentjamiebuilds/anti-fascist-mit-license

My IQ points dropped after reading two sentences.

@drepram You got it kid

madhavkhoslaa

comment created time in a month

issue commentjamiebuilds/unstated-next

useCallback usage

The best possible way you could do it is actually this:

let decrement = useCallback(() => setCount(count => count - 1), [])
let increment = useCallback(() => setCount(count => count - 1), [])

That way the callbacks never have to change and the state updates will work better with concurrency

AjaxSolutions

comment created time in 2 months

Pull request review commentboltpkg/bolt

Updated to skip workspaces that are missing a package.json

 export default class Config {     return await pkgUp(filePath);   } -  static async init(filePath: string): Promise<Config> {+  static async init(filePath: string): Promise<?Config> {     let fileContents;     try {       fileContents = await fs.readFile(filePath);     } catch (e) {       if (e.code === 'ENOENT') {-        logger.error(messages.cannotInitConfigMissingPkgJSON(filePath));+        // swallow error on missing config+        return;

I don't think you should return here, I think you should throw an error and catch that error elsewhere

kwelch

comment created time in 2 months

Pull request review commentboltpkg/bolt

Updated to skip workspaces that are missing a package.json

 describe('writeConfigFile', () => {     let json = { name: 'wat', version: '0.0.0' };     let fileContents =       JSON.stringify(json, null, 2).replace(/\n/g, '\r\n') + '\r\n';-    let config = await Config.init(filePath);+    let config = (await Config.init(filePath)) || {};

Why || {}?

kwelch

comment created time in 2 months

Pull request review commentboltpkg/bolt

Updated to skip workspaces that are missing a package.json

 export default class Config {     if (typeof bin === 'string') return bin;     return toObjectOfStrings(       bin,-      `package.json#bin must be an object of strings or a string. See "${-        this.filePath-      }"`+      `package.json#bin must be an object of strings or a string. See "${this+        .filePath}"`

Is your editor not using the same version of Prettier as Bolt?

kwelch

comment created time in 2 months

issue commentjamiebuilds/ghost-lang

Structs/Traits/Implementations

Note: This is a complete rip-off of Rust because out of similar patterns, I like theirs best.

jamiebuilds

comment created time in 2 months

issue openedjamiebuilds/ghost-lang

Structs/Traits/Implementations

Structs

struct Employee {
  name: String,
  title: String,
}

let employee = Employee { name = "Jamie Kyle", title = "Principal Engineer" }
employee.name
employee.title

Traits

trait Display {
  display = fn (self): String
}

trait Debug {
  debug = fn (self): String
}

Display.display(valueThatImplementsDisplay) # => String
Debug.debug(valueThatImplementsDebug) # => String

StructThatImplementsDisplay.display(structValue) # => String
StructThatImplementsDebug.debug(structValue) # => String

valueThatImplementsDisplay.display() # => String
valueThatImplementsDebug.debug() # => String

Implementations of Structs

implement Employee {
  new = fn (name: String, title: String) {
    return Employee { name, title }
  }

  changeTitle = fn (self, newTitle: String) {
    return Employee { name: self.name, title: newTitle }
  }
}

let employee = Employee.new(name = "Jamie Kyle", title = "Principal Engineer")
let newEmployee = employee.changeTitle("Shitposter Extraordinaire")

Implementations of Traits

implement Employee as Display {
  display = fn (self) {
    return "{self.name} ({self.title})"
  }
}

let employee = Employee { name = "Jamie Kyle", title = "Principal Engineer" }
employee.display() # "Jamie Kyle (Principal Engineer)"

Implementations of Structs and Traits

implement Employee as Display {
  new = fn (name: String, title: String) {
    return Employee { name, title }
  }

  changeTitle = fn (self, newTitle: String) {
    return Employee { name: self.name, title: newTitle }
  }

  display = fn (self) {
    return "{self.name} ({self.title})"
  }
}

let employee = Employee.new(name = "Jamie Kyle", title = "Principal Engineer")
let newEmployee = employee.changeTitle("Shitposter Extraordinaire")
newEmployee.display() # "Jamie Kyle (Shitposter Extraordinaire)"

Implementations of multiple Traits

implement Employee as Display, Debug {
  display = fn (self) {
    return "{self.name} ({self.title})"
  }

  debug = fn (self) {
    return "Employee \{ name = \"{self.name}\", title = \"{self.title}\" \}"
  }
}

let employee = Employee { name = "Jamie Kyle", title = "Principal Engineer" }
employee.display() # "Jamie Kyle (Principal Engineer)"
employee.debug() # "Employee \{ name = \"Jamie Kyle\", title = \"Principal Engineer\" \}"

created time in 2 months

delete branch jamiebuilds/ghost-lang

delete branch : changes

delete time in 2 months

push eventjamiebuilds/ghost-lang

Jamie Kyle

commit sha 86872d22a70cb09b316c2bf61a2f146af6747e21

Changes

view details

push time in 2 months

PR merged jamiebuilds/ghost-lang

Changes
  • Strings are only ever "double-quoted" (no single quoted strings, 'char may be used for chars in the future)
    • This simplifies the number of rules developers have to keep in their heads about strings, and reduces strings to 2 syntaxes instead of 4, which is still less than most languages which will have 6 or more.
    • I might re-add single quoted strings and say that they are functionally the same (both would require ' and " to be escaped), but I'd rather allow both as part of the formatter and format to one syntax
  • All strings can have interpolations
    • Again, making all strings equivalent
  • :symbols are now .properties
    • I think properties are a better way to think about symbols
    • I like the syntax I see in Swift better
    • I think there's a nice matchup between rec.prop and let x = .prop and rec[.prop]
  • Sets now use Set [...] instead of {...}
    • Sets are more similar to arrays and lists
    • Switching to keyword based syntax for data structures
  • Arrays now use Array [ ... ] instead of [| ... |]
    • Switching to keyword based syntax for data structures
  • Records now use { a = b } instead of { a: b }
    • I want to switch to have : ... reserved for "this is a type"
  • Maps now use Map { "a" = b } instead of {= "a" = b =}
    • Switching to keyword based syntax for data structures
+87 -92

0 comment

1 changed file

jamiebuilds

pr closed time in 2 months

push eventjamiebuilds/ghost-lang

Jamie Kyle

commit sha 3e19324462ffe93adcbefc3c3136dd29ab668560

Changes

view details

push time in 2 months

push eventjamiebuilds/ghost-lang

Jamie Kyle

commit sha 1e0d23a44a096a7c6b23f312e46a18c1ff22d80f

Update README.md

view details

Jamie Kyle

commit sha 3df5a36f2775c8f7ae79c7d8f1cee20a48fff552

Merge branch 'master' into changes

view details

push time in 2 months

push eventjamiebuilds/ghost-lang

Jamie Kyle

commit sha 1e0d23a44a096a7c6b23f312e46a18c1ff22d80f

Update README.md

view details

push time in 2 months

issue openedjamiebuilds/ghost-lang

Importing

Specifiers

Standard Library Packages

The import bare syntax is reserved for packages in the standard library.

import time
import math

Community Packages

Packages outside of the standard library will always be scoped.

import facebook/react
import jamiebuilds/unstated

Local Packages

Packages can also exist within a local project, and will follow the same scoping rules as community packages.

import mycompany/api
import mycompany/utils

Local Modules

import ./sibling
import ../parent
import ../../grandparent
import ../../path/to/cousin

Scoping rules

Bare Namespace

When importing a module with import ./mod the name mod becomes a namespace containing all of the modules exports

import ./mod
# mod.foo
# mod.bar
# mod.baz

Renamed Namespaces

You can rename namespaces using import ./mod as other.

import ./mod as other
# other.foo (mod.foo)
# other.bar (mod.bar)
# other.baz (mod.baz)

Renaming is useful to avoid clashes

Destructuring Exports

Alternatively, you can pick the exports you need without putting them on a namespace.

import ./mod as { foo, bar, baz }
# foo
# bar
# baz

Just like normal destructuring, you can also use ...rest to put any remaining exports onto a namespace.

import ./mod as { foo, ...rest }
# foo
# rest.bar
# rest.baz

Also like normal destructuring, you can also rename within destructuring.

import ./mod as { foo as bam, bar as bat }
# bam (foo)
# bat (bat)

Spread Exports

Inversely, you can spread all exports into the local scope.

import ./mod as ...
# foo
# bar
# baz

This can be extremely useful for DSLs where you want lots of things in scope:

import css as ...

let rule = css(
  display(.block),
  fontFamily(.sansSerif),
)

Default Exports

Modules can also have "default" exports by naming an export the same thing as the file name.

# foo.ghost:
let foo = fn () {} # because `foo` matches `foo.ghost` it gets special treatment (see below)
let bar = fn () {}
let baz = fn () {}

# other.ghost:
import ./foo                 # in scope: foo, foo.foo, foo.bar
import ./foo as bat          # in scope: bat (foo), bat.foo, bat.bar
import ./foo as { foo, bar } # in scope: foo, bar
import ./foo as { ...bat }   # in scope: bat.foo, bat.bar, bat.baz
import ./foo as ...          # in scope: foo, bar, baz

I want to have a concept of default exports because I don't want to end up with imports like this:

import ./foo
# foo.foo

import ./foo as { foo }
# foo

import ./bar # named "bar" just so you don't repeat "foo.foo"
# bar.foo

I think that it is okay to use the filename for this because I already consider the filename as part of the public API of a module.

created time in 2 months

PR opened jamiebuilds/ghost-lang

Changes
  • Strings are only ever "double-quoted" (no single quoted strings, 'char may be used for chars in the future)
    • This simplifies the number of rules developers have to keep in their heads about strings, and reduces strings to 2 syntaxes instead of 4, which is still less than most languages which will have 6 or more.
    • I might re-add single quoted strings and say that they are functionally the same (both would require ' and " to be escaped), but I'd rather allow both as part of the formatter and format to one syntax
  • All strings can have interpolations
    • Again, making all strings equivalent
  • :symbols are now .properties
    • I think properties are a better way to think about symbols
    • I like the syntax I see in Swift better
    • I think there's a nice matchup between rec.prop and let x = .prop and rec[.prop]
  • Sets now use Set [...] instead of {...}
    • Sets are more similar to arrays and lists
    • Switching to keyword based syntax for data structures
  • Arrays now use Array [ ... ] instead of [| ... |]
    • Switching to keyword based syntax for data structures
  • Records now use { a = b } instead of { a: b }
    • I want to switch to have : ... reserved for "this is a type"
  • Maps now use Map { "a" = b } instead of {= "a" = b =}
    • Switching to keyword based syntax for data structures
+87 -92

0 comment

1 changed file

pr created time in 2 months

create barnchjamiebuilds/ghost-lang

branch : changes

created branch time in 2 months

startedjamiebuilds/codeowners-enforcer

started time in 2 months

delete branch jamiebuilds/codeowners-enforcer

delete branch : empty-owners

delete time in 2 months

push eventjamiebuilds/codeowners-enforcer

Jamie Kyle

commit sha ff12d41d70d6dcc81d5eb3dfa0ff81d157f1354d

treat empty owners as unowned

view details

Jamie Kyle

commit sha 5d5c6ed3a4f863d5b201327c19d10cdc56d43724

1.0.2

view details

Jamie Kyle

commit sha e8bfa774a3d2def9d76ce8243d18e434a217b321

fix fmt

view details

Jamie Kyle

commit sha bf6c08d0a3499b76b9b2e1e534a3ac221ee8d13e

1.0.3

view details

Jamie Kyle

commit sha b6bb45103c3579c989206b89154d6d161f1f5303

Merge pull request #7 from jamiebuilds/empty-owners Empty owners

view details

push time in 2 months

release jamiebuilds/codeowners-enforcer

v1.0.3

released time in 2 months

delete tag jamiebuilds/codeowners-enforcer

delete tag : v1.0.2

delete time in 2 months

created tagjamiebuilds/codeowners-enforcer

tagv1.0.3

Enforce CODEOWNERS files on your repo

created time in 2 months

push eventjamiebuilds/codeowners-enforcer

Jamie Kyle

commit sha e8bfa774a3d2def9d76ce8243d18e434a217b321

fix fmt

view details

Jamie Kyle

commit sha bf6c08d0a3499b76b9b2e1e534a3ac221ee8d13e

1.0.3

view details

push time in 2 months

created tagjamiebuilds/codeowners-enforcer

tagv1.0.2

Enforce CODEOWNERS files on your repo

created time in 2 months

push eventjamiebuilds/codeowners-enforcer

Jamie Kyle

commit sha 18a126ae49cc7ab6a0b038864de67a0d906e1dfe

fix npm cli

view details

Jamie Kyle

commit sha c96939a459e5e0d692b691dff8b28388dd6fe97d

1.0.1

view details

Jamie Kyle

commit sha ff12d41d70d6dcc81d5eb3dfa0ff81d157f1354d

treat empty owners as unowned

view details

Jamie Kyle

commit sha 5d5c6ed3a4f863d5b201327c19d10cdc56d43724

1.0.2

view details

push time in 2 months

create barnchjamiebuilds/codeowners-enforcer

branch : empty-owners

created branch time in 2 months

delete branch jamiebuilds/codeowners-enforcer

delete branch : fix-npm-cli

delete time in 2 months

push eventjamiebuilds/codeowners-enforcer

Jamie Kyle

commit sha 18a126ae49cc7ab6a0b038864de67a0d906e1dfe

fix npm cli

view details

Jamie Kyle

commit sha c96939a459e5e0d692b691dff8b28388dd6fe97d

1.0.1

view details

push time in 2 months

release jamiebuilds/codeowners-enforcer

v1.0.1

released time in 2 months

created tagjamiebuilds/codeowners-enforcer

tagv1.0.1

Enforce CODEOWNERS files on your repo

created time in 2 months

delete tag jamiebuilds/codeowners-enforcer

delete tag : v1.0.1

delete time in 2 months

created tagjamiebuilds/codeowners-enforcer

tagv1.0.1

Enforce CODEOWNERS files on your repo

created time in 2 months

PR opened jamiebuilds/codeowners-enforcer

Fix npm cli
+29 -20

0 comment

8 changed files

pr created time in 2 months

create barnchjamiebuilds/codeowners-enforcer

branch : fix-npm-cli

created branch time in 2 months

delete branch jamiebuilds/codeowners-enforcer

delete branch : cargo-exclude

delete time in 2 months

push eventjamiebuilds/codeowners-enforcer

Jamie Kyle

commit sha 8374200c30f2aa5dd143c1c45289b837c5f7e590

Fix patterns in cargo exclude

view details

push time in 2 months

release jamiebuilds/codeowners-enforcer

v1.0.0

released time in 2 months

create barnchjamiebuilds/codeowners-enforcer

branch : cargo-exclude

created branch time in 2 months

created tagjamiebuilds/codeowners-enforcer

tagv1.0.0

Enforce CODEOWNERS files on your repo

created time in 2 months

delete branch jamiebuilds/codeowners-enforcer

delete branch : fix-cargo

delete time in 2 months

push eventjamiebuilds/codeowners-enforcer

Jamie Kyle

commit sha 800a776fd3dcbdefc370b6d039bfa58a106872e2

add fields to cargo.toml

view details

push time in 2 months

create barnchjamiebuilds/codeowners-enforcer

branch : fix-cargo

created branch time in 2 months

delete tag jamiebuilds/codeowners-enforcer

delete tag : v1.0.0

delete time in 2 months

release jamiebuilds/codeowners-enforcer

v1.0.0

released time in 2 months

created tagjamiebuilds/codeowners-enforcer

tagv1.0.0

Enforce CODEOWNERS files on your repo

created time in 2 months

delete tag jamiebuilds/codeowners-enforcer

delete tag : v1.0.0

delete time in 2 months

delete branch jamiebuilds/codeowners-enforcer

delete branch : release-1.0

delete time in 2 months

push eventjamiebuilds/codeowners-enforcer

Jamie Kyle

commit sha 686d674d5beb08eb2bdb405bf89fba8bbf5f2f81

rebuild cargo on version

view details

Jamie Kyle

commit sha c4033334fb0f720a5859a3b3bc23ccccf4a24c3b

1.0.0

view details

push time in 2 months

push eventjamiebuilds/codeowners-enforcer

Jamie Kyle

commit sha ba4358ca40bdee81d653dd3e50236909a5b28278

rebuild cargo on version

view details

Jamie Kyle

commit sha 04da1d2a2bb63273f6ffd3342be8df5688384b68

1.0.0

view details

push time in 2 months

more