question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Last breaking change suggestion: Tags

See original GitHub issue

When we first started using template tags with operators we wanted them initially to help express operators with a lot less internals (no parser or compiler). It also gave us the ability to compose paths:

state`foo.${input`bar`}`

This is super powerful stuff, but with the experience and late suggestions I think we made a mistake calling them “Operator tags”. With the latest suggested feature of router using:

{
  path: '/:id',
  map: {
    id: input`id`
  }
}

…operator tags is not the right name and scope for them. Also with suggestions on making connect work like:

connect({
  foo: state`foo.path`,
  someSignal: signal`some.signal`,
  item: state`items.${props`itemKey`}`
})

I think we should make a change. This is breaking, but I think it is important that we make the change so “template tags” can live out their full potential.

Tags

We just call them tags, and there are 5 of them by default:

import {state, input, signal, props, string} from 'cerebral/tags';

Tags gives information to operators, connect, module options etc. about targeting something in Cerebral. It is a general concept that can be used with whatever.

Operators

import {state, input, string, signal} from 'cerebral/tags';
import {set} from 'cerebral/operators';
import showMessage from '../factories/showMessage';

export default [
  set(state`foo`, input`foo`),
  showMessage(string`Hi there ${state`user.name`}`),
  httpGet('/something', {
    progress: signal`some.signal`
  })
]

Connect

import {state, signal, props} from 'cerebral/tags';
import {connect} from 'cerebral/react';

export default connect({
  foo: state`foo.path`,
  someSignal: signal`some.signal`,
  item: state`items.${props`itemKey`}`
})

Router and other options

import {state, input, signal} from 'cerebral/tags';

const routes = [{
  path: '/items/:id',
  map: {
    id: state`currentItemId`
  }
}]

Other reasons

Documentation

In documentation we can explain **TAGS ** as a general concept for targeting things, not something specifically to operators. Operators becomes less “magic” that way.

Scalability

It is now safe to introduce new tags that does not necessarily have to do with operators

Dynamic state retrieval in components

An issue now is that you often need two components to grab state. An example:

connect(props => ({
  item: `items.${props.currentItemKey}`
}))

The parent component has to depend on currentItemKey for the child component to dynamically depend on it and optimize itself. This issue becomes even worse with a computed:

connect(props => ({
  item: augmentedItem.props({itemKey: props.currentItemKey})
}))

Now there is a parent component -> child component -> computed dependency. With this new concept these two ones could be implemented as:

// Dynamic state deps
connect({
  item: state`items.${state`currentItemKey`}`
}, ...)
// Computed, same thing
const augmentedItem = Computed({
  item: state`items.${state`currentItemKey`}`
}, ...)

This is a huge deal in me opinion, cause it is difficult to reason about the component/computed dependency to get your shit done 😃

And yes… I know we stated no more breaking, but believe me. We have a pretty big refactor in our project to move to this… so when it comes to “is the juice worth the squeeze”, I am positive that it is 😃

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:7
  • Comments:13 (13 by maintainers)

github_iconTop GitHub Comments

2reactions
christianalfonicommented, Dec 18, 2016

@gaspard

  1. Correct, exported from “cerebral/tags”
  2. Correct, though props is used, not input. Tags are targets, so “Input” is not a valid target for connect, but it would be in a signal. Invalid target usage throws errors. Like signal is not a valid target for the set operator
  3. Actions are low level imperative code, not functional. I think it is better to keep actions imperative and signals functional 😃

@garth Jup, will be three args to connect. Extract stuff from Cerebral. State and signals. Second arg is the merge prop thingy. And last is component 😃

1reaction
christianalfonicommented, Dec 18, 2016

@maxfrigge Computed is a different discussion 😉 With this change computed works the way it does today

Read more comments on GitHub >

github_iconTop Results From Across the Web

Breaking Changes · microsoft/TypeScript Wiki - GitHub
TypeScript is a superset of JavaScript that compiles to clean JavaScript output. - Breaking Changes · microsoft/TypeScript Wiki.
Read more >
Keep a Changelog
Changed - Clarified the section on "Is there a standard change log format?". ### Fixed - Fix Markdown links to tag comparison URL...
Read more >
Conventional Commits
BREAKING CHANGE : a commit that has a footer BREAKING CHANGE: , or appends a ! after the type/scope, introduces a breaking API...
Read more >
How To Automatically Generate A Helpful Changelog From ...
A breaking change can be part of commits of any type. e.g., a fix: , feat: & chore: types would all be valid,...
Read more >
Deprecations by version - GitLab Docs
Some features cause breaking changes when they are removed. ... Use of the DAST.gitlab-ci.yml or DAST-latest.gitlab-ci.yml templates for API scans is ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found