profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/jnicklas/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.
Jonas Nicklas jnicklas JNicklas Consulting Gothenburg, Sweden https://blog.jnicklas.com/ Freelance developer working with Rust, Elixir, Phoenix, Ruby, Rails, JavaScript among other things. Open source enthusiast. Dancer.

abepetrillo/evergreen 452

Run Jasmine JavaScript unit tests, integrate them into Ruby applications.

jeroenvandijk/capybara-mechanize 207

RackTest driver for Capybara with remote request support

jnicklas/bistro_car 101

This project is obsolete. Use the asset pipeline now built into Rails instead.

jnicklas/carrierwave-example-app 29

An example app showcasing some features of the Ruby file upload library CarrierWave (http://github.com/jnicklas/carrierwave)

jnicklas/capybara_table 19

Capybara selectors and matchers for working with HTML tables

jnicklas/advanced_capybara 6

A repo containing the example app and slides of my advanced capybara talk

jnicklas/build_compile 3

Helper crate for build scripts which compile to Rust

jnicklas/capistrano 3

Remote multi-server automation tool

jnicklas/capybara_heroku 3

A small skeleton to run the capybara test app on Heroku

jnicklas/celluloid-stomp 3

Evented STOMP parser

pull request commentthefrontside/effection

Add visual debugger

Should we randomize the debugger port? Technically this works fine, but a fixed port has the advantage of being "stable" so a simple refresh in a browser window reconnects. On the other hand, collisions with other processes are a problem. A random port avoids this problem.

One option here is the concept of port "affinity" where we try and select the same port consistently. It's a bit more complicated, but could provide for a really nice experience. It might look like:

  1. try a fixed port (default 8800 or something constant)
  2. If fixed port is not available, see if .effection-port is available in the current working directory. If so, read the port contained therein, delete it and goto (1)
  3. If port is different to default, write the used port to .effection-port, otherwise, delete .effection-port
  4. at some interval check if the original default port is available, and if so, delete .effection-port if it exists

I'm also happy to punt on this and try to figure out as an enhancement.

jnicklas

comment created time in 3 hours

Pull request review commentthefrontside/effection

Update website

+---+id: events+title: Events+---++Asynchronous code often needs to interact with evented code. Using `async/await` this can be+quite challenging. Evented code often needs to be synchronous, because the timing of when to+subscribe and unsubscribe is very critical, otherwise race conditions can occur where events+get missed. Effection has powerful tools for working with Events.++## Single events++The simplest operation for working with events that Effection provides is the+`once` operation.  This operation blocks and waits for the event to occur. For+example, consider that we wanted to wait for the `open` even on a `WebSocket`,+we could do something like this:++``` javascript+import { main, once } from 'effection';++main(function*() {+  let socket = new WebSocket('ws://localhost:1234');++  yield once(socket, 'open');++  console.log('socket is open!');+});+```++The `once` operation works with both Node's `EventEmitter` events which use+`on/off` and the DOM `EventTarget` events which use+`addEventListener/removeEventListener`.++The `once` operation returns the argument passed to the event handler. For+example we could use this to grab the [`code`][wscode] that the socket closed+with:++``` javascript+import { main, once } from 'effection';++main(function*() {+  let socket = new WebSocket('ws://localhost:1234');++  yield once(socket, 'open');++  console.log('socket is open!');++  let closeEvent = yield once(socket, 'close');+  console.log('socket closed with code', closeEvent.code);+});+```++## Events with multiple arguments++In very rare cases, some event emitters pass multiple arguments to their event+handlers. For example the [ChildProcess][] in NodeJS emits both a status+code _and_ a signal to the 'exit' event. It would not be possible to read the+signal from the `exit` event using just the `once()` operation.++For cases like these, the `onceEmit` function exists, which works the same as+`once`, except it returns an array of all arguments passed to the event+handler.++## Recurring events++If you've been following the chapter on streams and subscriptions, you may+already have a feeling that it is not a good idea to repeatedly call+`once(socket, 'message')` to grab the messages sent to a WebSocket. The risk+here is that we miss messages if we're not very careful.++Instead we can use `on`. `on` is a very convenient function which takes an+event emitter and the name of an event, and returns a Stream of values.

Technically it takes either an EventEmitter (node) or an EventTarget (dom). We should probably even point that out since it is actually really handy because it lets you treat all event callbacks on all platforms uniformly.

jnicklas

comment created time in 4 hours

Pull request review commentthefrontside/effection

Update website

+---+id: futures+title: Futures+---++We mentioned in the [introduction][] that Effection is fundamentally+synchronous. What we mean by this is that any `Task` *could* complete+synchronously. Most of the time, tasks do take a while to complete, but+sometimes they do not, and can in fact complete instantaneously.++This is different from Promises and `async/await`. The Promise specification+requires that promises *always* complete asynchronously. And while they might+complete *very quickly*, they always have to release the event loop to do so.++There are good reasons for this behvaiour in promises, mostly related to error+handling, but requiring the event loop to be released also has downsides.++Let's look at an example of where releasing the event loop might be an issue.+Imagine you are writing an application for the browser and you want to handle+`click` events. We would like to intercept the click event and prevent the+default behaviour. We could write our code like this:++``` javascript+import { main, once } from 'effection';++main(function*() {+  let event = yield once(document.body, 'click');+  event.preventDefault();+  console.log('you clicked!');+});+```++If our `yield` point released the event loop after the click occurred, then the+default action has already happened by the time we call `preventDefault`. This+is no good, we need `once` to resolve *synchronously*.

This is a fantastic example.

jnicklas

comment created time in 4 hours

Pull request review commentthefrontside/effection

Update website

+---

It might be worth first starting on how to interpret an effection stack trace as a first step.

jnicklas

comment created time in 6 hours

Pull request review commentthefrontside/effection

Update website

+---+id: futures+title: Futures+---++We mentioned in the [introduction][] that Effection is fundamentally

missing link?

jnicklas

comment created time in 4 hours

Pull request review commentthefrontside/effection

Update website

+---+id: debugging+title: Debugging+---++> COMING SOON! The debugger is a work in progress, and this guides describes+> how the debugger will work eventually.++We have created a powerful visual debugger which is available both as a browser+extension for web applications which use Effection, and as a standalone+debugger for node applications.++## Using the browser extension++The browser extension is unfortunately not yet available from the chrome+and firefox extension stores. To build it manually, see the [devtools][]+package in the Effection repo on GitHub.++Once you have the browser extension installed, you will need to install the+`@effection/debug` package.++```+npm install @effection/debug+```++We recommend importing this package in the entry point of your application+(for example `src/index.js` or similar):++```+import '@effection/debug'+```++Just importing the package is enough.++If you start your application and open up the web inspector in your browser you+should now see a new "Effection" panel. Here you can see a tree view of all+currently running Effection tasks.++## Using the node debugger++Install the `@effection/debug` package:++```+npm install @effection/debug+```++You will need to import this package, and there are two main options that we+recommend for doing so.++The first option is to import it from the entry point of your application (for+example `src/index.js` or similar):++```+import '@effection/debug'+```++The second option is to run your `node` command with `-r @effection/debug`:++```+node -r @effection/debug src/index.js+```++Once your application starts, you should see Effection print a message like this:++```+[effection] debugger available on http://localhost:34556+```++Open the URL in a browser and you should see the visual debugger.++## Using labels++When using the visual debugger, we would like to be able to distinguish tasks+from each other, as well as seeing metadata about the tasks. We can do this+by applying labels.++Labels are key/value pairs, the key must be a string and the value must be a+string, number or boolean.++Labels also improve the "Effection trace" shown when an error occurs if you are+using `main`, so even if you aren't using the visual debugger, adding some labels+can make Effection code easier to debug.++We can apply labels when spawning a task:++``` javascript+import { run } from 'effection';++run(fetchWeekDay('cet'), {+  labels: {+    name: 'fetchWeekDay',+    timezone: 'cet'+  }+});+```++Or using `spawn`:++``` javascript+import { main, spawn } from 'effection';++main(function*() {+  yield spawn(fetchWeekDay('cet'), {+    labels: {+      name: 'fetchWeekDay',+      timezone: 'cet'+    }+  });+});+```++Or we can set labels on an operation by using the `withLabels` function:++``` javascript+import { main, withLabels } from 'effection';++main(function*() {+  yield withLabels(fetchWeekDay('cet'), {+    name: 'fetchWeekDay',+    timezone: 'cet'+  });+});+```++We could rewrite our `fetchWeekDay` operation to do this automatically for us:++``` javascript+import { withLabels } from 'effection';+import { fetch } from '@effection/fetch';++export function fetchWeekDay(timezone) {+  return withLabels(function*() {+    let response = yield fetch(`http://worldclockapi.com/api/json/${timezone}/now`);+    let time = yield response.json();+    return time.dayOfTheWeek;+  }, { name: 'fetchWeekDay', timezone });+}+```++This way, wherever we use `fetchWeekDay` it would be nicely labeled and easily+identifiable in the visual debugger.++## Dynamic labels++Another way of setting labels is through the `label` operation. This operation makes+it possible to set labels while the task is running:++``` javascript+import { once, label } from 'effection';++function *runSocketServer() {+  let socket = new WebSocket('ws://localhost:1234');++  yield label({ state: 'pending' });++  yield once(socket, 'open');++  yield label({ state: 'open' });++  console.log('socket is open!');++  let closeEvent = yield once(socket, 'close');++  yield label({ state: 'closed' });+  console.log('socket closed with code', closeEvent.code);+};+```++This can give you some insight into the current state of a task.++## Function names++A final trick is that if our operation is a generator *function*, then we can name the+function to automatically set the `name` label:++``` javascript+import { withLabels } from 'effection';+import { fetch } from '@effection/fetch';++export function fetchWeekDay(timezone) {+  return function* fetchWeekDay() {+    let response = yield fetch(`http://worldclockapi.com/api/json/${timezone}/now`);+    let time = yield response.json();+    return time.dayOfTheWeek;+  }+}+```++Unfortunately, there is no way to obtain the name of the generator *function*+from a `Generator`, so the following does *not* set any labels:++``` javascript+import { withLabels } from 'effection';+import { fetch } from '@effection/fetch';++export function *fetchWeekDay(timezone) {+  let response = yield fetch(`http://worldclockapi.com/api/json/${timezone}/now`);+  let time = yield response.json();+  return time.dayOfTheWeek;+}+```+

Worth including a note that while we do our best to label a generator function (and async function), it's not foolproof, so when in doubt, just use explicit labels to improve the visualization and debugging experience for you and for any consumers of code?

jnicklas

comment created time in 4 hours

Pull request review commentthefrontside/effection

Update website

+---+id: collections+title: Streams and Subscriptions+---++Effection ships with a powerful library for working with streams of values.+This allows you to create complex systems where evented code, stateful code and+concurrent asynchronous code all are working together seamlessly.++If you're familiar with reactive programming libraries such as [Rx.js][rx],+then this functionality should feel familiar. It is also somewhat similar to+[asynchronous iterators][].++## Queue++Before we look at Subscriptions and Streams, let's look at another powerful+concept: the Queue. Effection ships with a `createQueue` functions which returns+a `Queue`. It can be used like this:++``` javascript+import { main, createQueue } from 'effection';++main(function*() {+  let queue = createQueue();++  queue.send('hello');+  queue.send('world');++  console.log(yield queue.expect()); // logs 'hello'+  console.log(yield queue.expect()); // logs 'world'+});+```++As you can see, we can push values into the queue using `send`, and then we can+fetch values from the queue using `expect`.

Queues are a very low-level mechanism that you basically never, ever use; even if you're a really advanced Effection developer. As such, it feels as though it should be introduced at the very end. I see that we need some way of introducing subscription first, but maybe we can use a practical example instead? Either way, it feels like Subscription should get the top billing.

jnicklas

comment created time in 6 hours

Pull request review commentthefrontside/effection

Update website

+---+id: futures+title: Futures+---++We mentioned in the [introduction][] that Effection is fundamentally+synchronous. What we mean by this is that any `Task` *could* complete+synchronously. Most of the time, tasks do take a while to complete, but+sometimes they do not, and can in fact complete instantaneously.++This is different from Promises and `async/await`. The Promise specification+requires that promises *always* complete asynchronously. And while they might+complete *very quickly*, they always have to release the event loop to do so.++There are good reasons for this behvaiour in promises, mostly related to error
There are good reasons for this behavior in promises, mostly related to error
jnicklas

comment created time in 4 hours

Pull request review commentthefrontside/effection

Update website

+---+id: collections+title: Streams and Subscriptions+---++Effection ships with a powerful library for working with streams of values.+This allows you to create complex systems where evented code, stateful code and+concurrent asynchronous code all are working together seamlessly.++If you're familiar with reactive programming libraries such as [Rx.js][rx],+then this functionality should feel familiar. It is also somewhat similar to+[asynchronous iterators][].++## Queue++Before we look at Subscriptions and Streams, let's look at another powerful+concept: the Queue. Effection ships with a `createQueue` functions which returns+a `Queue`. It can be used like this:++``` javascript+import { main, createQueue } from 'effection';++main(function*() {+  let queue = createQueue();++  queue.send('hello');+  queue.send('world');++  console.log(yield queue.expect()); // logs 'hello'+  console.log(yield queue.expect()); // logs 'world'+});+```++As you can see, we can push values into the queue using `send`, and then we can+fetch values from the queue using `expect`.++## Subscription++You have already met a Subscription, because `Queue` is in fact a+`Subscription`! Or rather you can think of the *receiving* end of the queue as+a subscription.++A subscription is a basically an iterator over a stream of values. Taking the
A subscription is an iterator over a stream of values. Taking the
jnicklas

comment created time in 6 hours

push eventthefrontside/effection

minkimcello

commit sha 9cfc2f03fa4a806708df53e0a2e0099894157db7

Change out directory and remove from gitignore

view details

minkimcello

commit sha 6cbc84d4a0b8fda074270af3d73b06743a16beb7

Fix patch

view details

push time in 6 hours

push eventthefrontside/effection

minkimcello

commit sha 66554fbb2797a20809db5e0449487e772695462b

Remove generated typedocs that should be ignored

view details

push time in 6 hours

push eventthefrontside/effection

minkimcello

commit sha d004f09307df2b11c9f35fb487127ec527ea8571

Add patch to skip ts error and specify separate entry

view details

minkimcello

commit sha de76459c33eb18880df7ea55033caf681adf05ac

Configure typeDocEntry property per package

view details

minkimcello

commit sha 98f12bc4b0a3ea0bd5610b4e2c7e2f32a8added4

Update notes

view details

push time in 6 hours

pull request commentthefrontside/effection

Configure CI for API docs

The problem is that the linkability and navigation structure is the most important part of API docs, and that aspect of it just did not work very well with the translation. While it looked better, it was cumbersome to navigate.

@minkimcello Is there a way to generate a cache key from the typedocs? That would seem like a more general solution. I wonder if anybody has tried it.

minkimcello

comment created time in 8 hours

issue commentthefrontside/effection

task.spawn as operation

I'll throw together a PR today.

cowboyd

comment created time in 8 hours

issue openedthefrontside/bigtest

Interactor docs don't explicitly mention that interactors wait for elements to interact

Arguably the killer feature of interactors is that they decouple interaction with DOM elements from the timing of those elements becoming available. However, we still field questions quite often on "how do I make sure an element is available before interacting with it."

The docs should feature this aspect of interacors prominently. Perhaps we should have an "Introduction" part of the guide instead of jumping right into the "getting started" part of it.

created time in 8 hours

issue commentthefrontside/effection

Where should warning go if an exception percolates to the top.

Agree. Let's leave this open for now, and we can have a think on it later.

cowboyd

comment created time in 9 hours

create barnchthefrontside/bigtest

branch : filter-getters

created branch time in 15 hours

pull request commentthefrontside/bigtest

Filter delegation

⚠️ No Changeset found

Latest commit: dcd83d1f1709fe67b21c72f4e4c8508b707ee6ef

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

<details><summary>This PR includes no changesets</summary>

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

jnicklas

comment created time in 16 hours

issue closedthefrontside/effection

pass argv: string[] to main operation

@effection/node main() is designed to implement the main method of a node process and yet we don't actually do the work of coupling to process.argv which has to be done manually, but in fact this is something that you invariably need to do.

Proposal, instead of

function main(operation: Operation<T>): Context<T>;

should be:

function main((argv: string[]) => Operation<T>): Context<T>;

That way


import { main } from '@effection/node';

main(function*() {
  yargs(process.argv);
});

becomes

import { main } from '@effection/node';

main(function*(argv) {
  yargs(argv);
});

closed time in a day

cowboyd

issue commentthefrontside/effection

pass argv: string[] to main operation

@cowboyd given that main now also works in the browser, do you still feel we should do this, since there isn't really an equivalent to argv in the browser?

We could say [] in the browser, but I don't feel strongly about this. I say let's not do it now since it can be a forward compatible change if we decide to do it later, but it will not be a backwards compatible change if we decide we don't want it in the future

cowboyd

comment created time in a day

push eventthefrontside/effection

dependabot[bot]

commit sha a3dedb609994aa8720553eb8cb9691845b44f0dd

Bump url-parse from 1.4.7 to 1.5.1 in /website Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.4.7 to 1.5.1. - [Release notes](https://github.com/unshiftio/url-parse/releases) - [Commits](https://github.com/unshiftio/url-parse/compare/1.4.7...1.5.1) --- updated-dependencies: - dependency-name: url-parse dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>

view details

Jonas Nicklas

commit sha 0b6f172d9d86b58dc4de1e02907033e18e4070c9

WebsocketServer can accept HTTP server and port can be omitted

view details

dependabot[bot]

commit sha 30c98b7a235675f0cd0103319a91ccc112a2e6a3

Bump lodash from 4.17.20 to 4.17.21 in /website Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21) --- updated-dependencies: - dependency-name: lodash dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>

view details

dependabot[bot]

commit sha 3d54d99aa645ebdcaec2f672a23cc0cb76900152

Bump postcss from 7.0.35 to 7.0.36 in /website Bumps [postcss](https://github.com/postcss/postcss) from 7.0.35 to 7.0.36. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/7.0.35...7.0.36) --- updated-dependencies: - dependency-name: postcss dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>

view details

dependabot[bot]

commit sha 607ea66fe04b7130b1d1384ca2d582c62a29aaeb

Bump ua-parser-js from 0.7.22 to 0.7.28 in /website Bumps [ua-parser-js](https://github.com/faisalman/ua-parser-js) from 0.7.22 to 0.7.28. - [Release notes](https://github.com/faisalman/ua-parser-js/releases) - [Commits](https://github.com/faisalman/ua-parser-js/compare/0.7.22...0.7.28) --- updated-dependencies: - dependency-name: ua-parser-js dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>

view details

Jonas Nicklas

commit sha 80c4beca2ee7c0d45f6bf9c21cd33adaa6cc37f7

Merge pull request #391 from thefrontside/dependabot/npm_and_yarn/website/lodash-4.17.21 Bump lodash from 4.17.20 to 4.17.21 in /website

view details

dependabot[bot]

commit sha 99aaa0503102be10617ab379529c6c7f72ab9c90

Bump y18n from 4.0.0 to 4.0.3 in /website Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.3. - [Release notes](https://github.com/yargs/y18n/releases) - [Changelog](https://github.com/yargs/y18n/blob/y18n-v4.0.3/CHANGELOG.md) - [Commits](https://github.com/yargs/y18n/compare/v4.0.0...y18n-v4.0.3) --- updated-dependencies: - dependency-name: y18n dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>

view details

Jonas Nicklas

commit sha 8305ea6d08247f4cd58200ae74ccd29893bcc620

Merge pull request #378 from thefrontside/v2-websocket-http-server WebsocketServer can accept HTTP server and port can be omitted

view details

Jonas Nicklas

commit sha f7e33445bfc32ece4735c901ef6b25698dd0d1d7

Fix incorrect name in interface

view details

Jonas Nicklas

commit sha 38ac384ea0e517a599843641aff36efe91091b90

Merge pull request #398 from thefrontside/dependabot/npm_and_yarn/website/y18n-4.0.3 Bump y18n from 4.0.0 to 4.0.3 in /website

view details

Jonas Nicklas

commit sha c0daa8c4f6e637d9152fe550fc9e747dada89d76

Merge pull request #393 from thefrontside/dependabot/npm_and_yarn/website/ua-parser-js-0.7.28 Bump ua-parser-js from 0.7.22 to 0.7.28 in /website

view details

Jonas Nicklas

commit sha 1f5d958b117ba384601a8f2c985cc17c411680fe

Merge pull request #392 from thefrontside/dependabot/npm_and_yarn/website/url-parse-1.5.1 Bump url-parse from 1.4.7 to 1.5.1 in /website

view details

dependabot[bot]

commit sha c7496df06b30048a7ad7515a123f9be9aae0f48d

Bump elliptic from 6.5.3 to 6.5.4 in /website Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4. - [Release notes](https://github.com/indutny/elliptic/releases) - [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4) --- updated-dependencies: - dependency-name: elliptic dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>

view details

dependabot[bot]

commit sha a9e9435352e315d23b1ff5b9c542d3d13e3c2027

Bump prismjs from 1.22.0 to 1.23.0 in /website Bumps [prismjs](https://github.com/PrismJS/prism) from 1.22.0 to 1.23.0. - [Release notes](https://github.com/PrismJS/prism/releases) - [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md) - [Commits](https://github.com/PrismJS/prism/compare/v1.22.0...v1.23.0) --- updated-dependencies: - dependency-name: prismjs dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>

view details

Jonas Nicklas

commit sha 1142fab3947dc8dbacbd71c784017f5b0d6d59d1

Merge pull request #401 from thefrontside/dependabot/npm_and_yarn/website/prismjs-1.23.0 Bump prismjs from 1.22.0 to 1.23.0 in /website

view details

Jonas Nicklas

commit sha 581b940b0c57ab6bf1de11c61a8f0f92f7575142

Merge pull request #400 from thefrontside/dependabot/npm_and_yarn/website/elliptic-6.5.4 Bump elliptic from 6.5.3 to 6.5.4 in /website

view details

Jonas Nicklas

commit sha 4ff7a098512d4e17f04e419ec664bb681010084f

Merge pull request #395 from thefrontside/dependabot/npm_and_yarn/website/postcss-7.0.36 Bump postcss from 7.0.35 to 7.0.36 in /website

view details

dependabot[bot]

commit sha d01c3a92d43dc194ed9777d6c7a220045842c899

Bump ini from 1.3.5 to 1.3.8 in /website Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8. - [Release notes](https://github.com/isaacs/ini/releases) - [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8) --- updated-dependencies: - dependency-name: ini dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>

view details

Jonas Nicklas

commit sha 508f4ad5e51df24af5ffb81da3908db18eebaf9a

Merge pull request #399 from thefrontside/v2-yielding-to-miss Fix incorrect name in interface

view details

Jonas Nicklas

commit sha 92c2691a772eaeb97e7f309554e2a96df3c54b64

Upgrade tsconfig

view details

push time in a day

push eventthefrontside/effection

minkimcello

commit sha 5a994984d4d7b8046c1eb0b2dc2f329e0ed6f2f6

Upgrade ts to 4.0.0 and bring typedoc to root

view details

push time in a day

push eventthefrontside/effection

minkimcello

commit sha 41eeb8c326f0f63524cd0fc5dd6b4baa90edda54

Shorten docusaurus build script for website

view details

minkimcello

commit sha 5dd3c9fe23c78434131f5994e97c470d3ae6cb56

Upgrade ts to 4.0.0 and bring typedoc to root

view details

push time in a day

Pull request review commentthefrontside/effection

Update website

+---+id: lifecycle+title: Task Lifecycle+---++We have talked about how Effection operations are able to clean up after+themselves, but how are they able to do this, and how can you implement your+own operations which clean up after themselves?++### Halt++In order to understand the lifecycle of a Task, we must first understand the+concept of halting a Task.++In Effection, any task can be halted:++``` javascript+import { main } from 'effection';++let task = main(function*() {+  yield+});++task.halt();+```++Or:++``` javascript+main(function*() {+  let task = yield spawn();+  yield task.halt();+});+```++Halting a Task means that the task itself is cancelled, it also causes any Task+that has been spawned from the Task to be halted.

Would it be worth mentioning that halting a task won't shut down the parent task the way an error will?

jnicklas

comment created time in a day

Pull request review commentthefrontside/effection

Update website

+---+id: resources+title: Resources+---++As we discussed in the chapter on [tasks][], an [Operation][] can be one of+several things, one of which is a [Resource][]. In this chapter we will explain+what a resource is and why you might want to use one.++## The resource criteria++Resources can seem a little complicated, but the reason for their existence is+rather simple. Sometimes there are operations which meet the following criteria:++1. They are long running+1. We want to be able to interact with them while they are running++## Why resources?++As an example, let's consider that our program opens a Socket, and we want to be+able to send messages to this socket while it is open. This is fairly simple+to write using regular operations like this:++``` javascript+import { main } from 'effection';+import { Socket } from 'net';++main(function*() {+  let socket = new Socket();+  socket.connect(1337, '127.0.0.1');++  yield once(socket, 'connect');++  socket.write('hello');++  socket.close();+});+```++This works, but there are a lot of details we need to remember to use the socket+safely. It would be nice if we could create a friendly abstraction that we could+reuse in all of our code that uses socket.++We know we want to close this socket once we're done, so our first attempt might+look something like this:++``` javascript+import { once } from 'effection';++export function *createSocket(port, host) {+  let socket = new Socket();+  socket.connect(port, host);++  yield once(socket, 'connect');++  try {+    yield+    return socket;+  } finally {+    socket.close();+  }+});+```++But when we actually try to use our `createSocket` operation, we run into a problem:++``` javascript+import { main } from 'effection';+import { createSocket } from './create-socket';++main(function*() {+  let socket = yield createSocket(1337, '127.0.0.1'); // this blocks forever+  socket.write('hello'); // we never get here+});+```++## Using resources++Remember our criteria from before:++1. Socket is a long running process+1. We want to interact with the socket while it is running by sending messages to it++This is a good use-case for using a Resource. Let's look at how we can rewrite+`createSocket` using resources, an implementation might look something like+this:++``` javascript+import { once, spawn } from 'effection';++export function createSocket(port, host) {+  return {+    *init() {+      let socket = new Socket();+      socket.connect(port, host);++      yield spawn(function* closeSocket() {+        try {+          yield+        } finally {+          socket.close();+        }+      });++      yield once(socket, 'connect');++      return socket;+    }+  }+});+```++Before we unpack what's going on, let's just note that how we use `createSocket` has+not changed at all, only it now works as we expect!++``` javascript+import { main } from 'effection';+import { createSocket } from './create-socket';++main(function*() {+  let socket = yield createSocket(1337, '127.0.0.1'); // waits for the socket to connect+  socket.write('hello'); // this works+  // once `main` finishes, the socket is closed+});+```++## How resources work++Let's take a look at the implementation of `createSocket`. Effection considers+any object which has an `init` function a Resource, and so the object returned+from `createSocket` is a Resource.

I think we should mention this before the example on line 88.

jnicklas

comment created time in a day

Pull request review commentthefrontside/effection

Update website

+---+id: lifecycle+title: Task Lifecycle+---++We have talked about how Effection operations are able to clean up after+themselves, but how are they able to do this, and how can you implement your+own operations which clean up after themselves?++### Halt++In order to understand the lifecycle of a Task, we must first understand the+concept of halting a Task.++In Effection, any task can be halted:++``` javascript+import { main } from 'effection';++let task = main(function*() {+  yield+});++task.halt();+```++Or:++``` javascript+main(function*() {+  let task = yield spawn();+  yield task.halt();+});+```++Halting a Task means that the task itself is cancelled, it also causes any Task+that has been spawned from the Task to be halted.++### Return++If a Task is driving a generator, we call `return()` on the generator. This behaves+somewhat similarly to if you would put a `return` statement at the current yield point.++``` javascript+import { main } from 'effection';++let task = main(function*() {+  yield // we will `return` from here+  console.log('we will never get here');+});++task.halt();+```

I'm guessing the return() you refer to is an internal thing?

Regarding the point you're making here, doesn't this apply to normal generator functions too (and not an effection-specific thing)?

Also do we need the task.halt() in this particular example?

jnicklas

comment created time in a day

push eventthefrontside/bigtest

dependabot[bot]

commit sha ed76168c870a13ac775dbd3180e897addcff67dd

Bump browserslist from 4.12.1 to 4.16.6 Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.12.1 to 4.16.6. - [Release notes](https://github.com/browserslist/browserslist/releases) - [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md) - [Commits](https://github.com/browserslist/browserslist/compare/4.12.1...4.16.6) Signed-off-by: dependabot[bot] <support@github.com>

view details

Jonas Nicklas

commit sha 71c121b32f19cf3553c2eccb408ff7bc986c2949

Merge pull request #934 from thefrontside/dependabot/npm_and_yarn/browserslist-4.16.6 Bump browserslist from 4.12.1 to 4.16.6

view details

github-actions[bot]

commit sha 9795bbb0490b5630599c779ce9d8e15a3f5ec17a

Version Packages

view details

push time in 2 days

pull request commentthefrontside/bigtest

Bump ws from 5.2.2 to 5.2.3

⚠️ No Changeset found

Latest commit: 067a7f81dd3a8113d69681a2b441d66ba2b69877

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

<details><summary>This PR includes no changesets</summary>

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

dependabot[bot]

comment created time in 2 days

pull request commentthefrontside/bigtest

Bump color-string from 1.5.3 to 1.5.5

⚠️ No Changeset found

Latest commit: 85d8873124f16fcda2f7bb78dd60068668bcb451

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

<details><summary>This PR includes no changesets</summary>

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

dependabot[bot]

comment created time in 2 days

PR opened thefrontside/bigtest

Bump ws from 5.2.2 to 5.2.3

Bumps ws from 5.2.2 to 5.2.3. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/websockets/ws/releases">ws's releases</a>.</em></p> <blockquote> <h2>5.2.3</h2> <h1>Bug fixes</h1> <ul> <li>Backported 00c425ec to the 5.x release line (76d47c14).</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/websockets/ws/commit/6dd88e7e968ef2416445d8f8620c17d99b15c77c"><code>6dd88e7</code></a> [dist] 5.2.3</li> <li><a href="https://github.com/websockets/ws/commit/76d47c1479002022a3e4357b3c9f0e23a68d4cd2"><code>76d47c1</code></a> [security] Fix ReDoS vulnerability</li> <li>See full diff in <a href="https://github.com/websockets/ws/compare/5.2.2...5.2.3">compare view</a></li> </ul> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
  • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
  • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
  • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the Security Alerts page.

</details>

+3 -3

0 comment

1 changed file

pr created time in 2 days