Support for typed actions (Typescript)

Related to these two issues:

https://github.com/rackt/redux/issues/355
https://github.com/rackt/redux/issues/437

Hi Dan,
The company I am with is using Redux as well as Typescript, and we would like to add some additional compile-time guarantees to our actions. Currently this isn't possible because of the restriction that actions must be plain objects.  But I had code using Typescript classes that (when the redux devtools were enabled) could still record, cancel and replay actions just fine (using the code I posted in issue 355).
When I remove the devtools I just get errors from that check that actions are plain objects and execution stop there. To me it seems like it is too strict, checking more than is really required. I would much rather have a check that requires that the actions are serializable. I know performance is a concern - IMO it shouldn't have to guarantee/prove they are serializable, just check that the action objects themselves say that they are, and then trust them.
(Not sure why the check doesn't also fail when devtools are enabled - maybe you can shed light on that).
I would really like to be able to leverage the advantages of both Typescript and Redux. Hope you can help me (and others using both of these tools) arrive at a solution.
I also want to reiterate that (as much as I wish it were otherwise!) Typescript does not have discriminated unions, so solutions based on that approach will not work.
Thank you!

Does TypeScript let you type-check shapes of plain objects instead of defining classes?
My only issue is with using instances of classes for actions.
Wouldn't TypeScript interfaces be enough to strongly type plain object actions?

Almost - the problem with those is that they only exist at compile-time. So the reducer will have no way to tell which incoming action is of which interface. ...Unless I keep the 'type' property on each action and then manually cast them after checking that property. And at that point I'm not getting any extra type-safety over just leaving them as plain objects.

@nickknw Well there can be no way to strong type those actions! I mean it wouldn't be possible even if it was C#! It's just how the architecture is, it doesn't have anything to do with redux. I my self use redux with typescript too. And best I could come up with was having interfaces with the same name as my actionTypes, keep the interfaces and constants in the same place, enforce my actionCreators to respect the typings and cast inside the reducers. It's not so hard to maintain and it gives me the type safety I need with clear intentions why the interfaces exist. I would suggest you to consider this approach, it worked for me :grin: and my project is kinda huge :D

You said that this is because 'record/replay and associated features won't work with an action class' and I get that those are valuable features and don't want to lose them. But I had code using Typescript classes that (when the redux devtools were enabled) could still record, cancel and replay actions just fine (using the code I posted in issue 355).

Yes but then if you use persistState() enhancer, serialize them, and later restore your state and deserialize them, they will no longer work because your code is relying on instanceof checks.
The “plain objects” isn't really the point. What we want to enforce is that you don't rely on actions being instances of specific classes in your reducers, because this will never be the case after (de)serialization.

In other words, this is an anti-pattern:
function reducer(state, action) {
  if (action instanceof SomeAction) {
    return ...
  } else {
    return ...
  }
}

If we make it possible for TypeScript users, I know JavaScript users will be tempted and will abuse this because many people coming from traditional OO languages are used to writing code this way. Then they will lose benefits of record/replay in Redux.
One of the points of Redux is to enforce some restrictions that we find important, and that, if not enforced, don't allow for rich tooling later on. If we let people use classes for actions, they will do so, and implementing something like redux-recorder will be impossible because there's no guarantee people use plain object actions. Especially if boilerplate projects suddenly decide to adopt classes because “wow, it’s allowed now, it must be a great idea”.

What we want to enforce is that you don't rely on actions being instances of specific classes in your reducers, because this will never be the case after (de)serialization.

I think this is where you lost me. I don't follow why serializing and deserializing an object necessarily means that it will lose its class-related information.

let actions = [new SomeAction(), new OtherAction()];
let json = JSON.stringify(actions);
let revivedActions = JSON.parse(json);
// reducers no longer understand revivedActions because type info is stripped.

Another reason why I don't want to allow people to create classes for actions is because this will encourage them to
a) Create class hierarchies
b) Put logic there, e.g. “patch” method from https://github.com/rackt/redux/issues/437#issue-99905895
Both are contrary to how I intend Redux to be used. However React showed that if you give people ES6 classes, they will use inheritance even when there are much better alternatives, just because it's so entrenched in software development. It's hard to let go of old habits unless you're forced to.
It's sad that TypeScript forces you to turn things you want to strongly type into classes, but I believe this to be a fault of TypeScript, not ours. As described in https://github.com/rackt/redux/issues/992#issuecomment-153138035, I find casting to be the best solution we can offer. You can also publish redux-typescript-store project with createStore() that doesn't have this restriction, but I'm still not compelled to remove it.

Finally: for the record, I'm not hatin' on classes.
That's not my point.
My only point is that actions should be passive descriptions of what happened. If we allow them to be class instances, people will build weird abstractions on top of actions with classes, and suffer as a result. Do not want.

Ahh okay, thank you for the example. I didn't realize that JSON.stringify discards prototype information. It doing that makes sense to me in retrospect, given the limitations of what JSON can store.

One of the points of Redux is to enforce some restrictions that we find important, and that, if not enforced, don't allow for rich tooling later on.

Yes, I get that, am on board with it, and don't want to compromise on the guarantees the tools can count on. I don't want to create class hierarchies or attach logic to classes, just want to be able to tell them apart at compile-time.

It's sad that TypeScript forces you to turn things you want to strongly type into classes, but I believe this to be a fault of TypeScript, not ours.

Interfaces work well enough for what they were designed for, but I agree it is unfortunate for this use case that they don't keep any type information around at runtime (or allow for a runtime check 'does this conform to this interface' in another way).

My only point is that actions should be passive descriptions of what happened.

100% agree with you here

If we allow them to be class instances, people will build weird abstractions on top of actions with classes, and suffer as a result.

Ugh, I suppose that's true too.

I still think there might be room for a middle ground here, with a slightly more flexible way of serializing actions. There's the 'reviver' and 'replacer' parameters for parse and stringify - maybe there is a way to create a serialization function that can preserve enough information for me to pass some basic type information through but also know enough about the structure to warn/error about the scenarios you want to prevent.
Would rather not go down the route of manually casting actions - I might if nothing else works out but at that point the types aren't adding a lot of value for the effort.

And yes it would be nice if Typescript had more flexible typing options so that I didn't have to use classes but that isn't something I can realistically affect or count on changing any time soon.

maybe there is a way to create a serialization function that can preserve enough information for me to pass some basic type information through but also know enough about the structure to warn/error about the scenarios you want to prevent.

This would involve user implementing functions that map type strings to classes which is pretty much manual casting all over again. And we don't want users to implement this sort of stuff to get record/replay working. This is another point of Redux: you get hot reloading, record/replay for free, without implementing serialize(), hydrate(), etc.

This would involve user implementing functions that map type strings to classes which is pretty much manual casting all over again.

Ideally it would just involve implementing a pair of functions that do that, and then all the action classes would be implemented in a way that those functions could serialize them. So instead of possibly introducing human error once for each different action handled, it would just be once.

And we don't want users to implement this sort of stuff to get record/replay working.

Not what I was proposing - this could be something that is opt-in. If you don't need to do it everything works as normal. I understand you might not be enthusiastic about opening that can of worms. I don't mind digging into this at some point and see if I can find some way to preserve the type information I want without opening the door wide open for everything else.

This is another point of Redux: you get hot reloading, record/replay for free, without implementing serialize(), hydrate(), etc.

This is a great benefit of Redux and I wouldn't want to change that. But I would also love to get some compile-time guarantees for actions while using Redux.

I don't want to change it in core for reasons above. As I said previously, please feel free to create redux-typescript package with TS-friendly version of createStore and (maybe?) other Redux functions. We don't intend to have breaking changes in Redux at this point so you shouldn't worry about keeping up with the API. And as long as the API matches, such custom store will work just fine. (And its implementation is tiny, check out createStore source).

I think you can solve the issue by using TypeScript 1.6 user-defined type guards (see http://blogs.msdn.com/b/typescript/archive/2015/09/16/announcing-typescript-1-6.aspx).
Define an interface for the base action and one for each other action. Additonally for each Action create a isXYZAction(a: Action) function which checks the type based on the value of the type field (which is defined in the base action interface.
Use these functions in the reducer to safely access fields of the specific actions after the check:
interface Action {
  type: string
}

interface AddTodoAction extends Action {
  text: string
}

function isAddTodoAction(action: Action): a is AddTodoAction {
  return action.type == ADD_TODO;
}

function reducer(state: any, action: Action) {
  if (isTodoAction(action)) {
    // typesafe access to action.text is possible here
  } else {
    return ...
  }
}

@Matthias247 that's exactly what I need, thanks!

@Matthias247 That's fantastic, thank you for pointing that out! Did not know about that feature, that is exactly what I need :)

I'm using FSA and I found it very convenient to have generic Action interface with type parameter corresponding to payload type:
interface Action<T>{
  type: string;
  payload: T;
  error?: boolean;
  meta?: any;
}

Then I export payload type alongside action type using same name:
export const ADD_TODO = 'ADD_TODO';
export type ADD_TODO = {text: string};

This way when you import ADD_TODO, you actually import both action type and payload type:
import {ADD_TODO} from './actions';
import {handleActions} from 'redux-actions';

const reducer = handleActions({
  [ADD_TODO]: (state, action:Action<ADD_TODO>) => {
    // enabled type checking for action.payload
    // ...
  }
});

I had the same problem, and found the solution here: http://www.bluewire-technologies.com/2015/redux-actions-for-typescript/. It's basically a generalization of solution proposed by @Matthias247, and it has a clear advantage: no need to define a is*Action() function for each action.
This solution seems to work, but it needs 2 additions for Redux. First you need a middleware for transforming actions to plain objects (redux does this checking and throws an error). This could be as simple as:
// middleware for transforming Typed Actions into plain actions
const typedToPlain = (store: any) => (next: any) => (action: any) =>  {
    next(Object.assign({}, action));
};

And if you use tslint, it will complain about unused _brand property, so the only thing you can do is to enclose it in tslint ignore comments:
/* tslint:disable */
private _brand: NominalType;
/* tslint:enable */

BTW, I didn't use NominalType as it seemed to add to the boilerplate, and just used directly void type.

For those interested in a 'flux' lib with native support for typescript, you may want to check: https://github.com/AlexGalays/fluxx#typescript-store

@AlexGalays Good job so far! Didn't you think of instead forking Redux and adding TypeScript support to it, so the community gets all the features Redux and its friend modules provide, like DevTools, middleware, sagas etc?

@sompylasar I asked myself that same question at some point: "Why not just use redux, it looks pretty close to what I want from a state container"; But 1) a bit of competition is always good (Speaking in general. fluxx obviously get obliterated by redux competition wise),  2) I wish to keep it simple and easy to learn for my coworkers. That's what I get with fluxx that I don't get with redux: Just one npm dependency for all my needs (yet it's even tinier than redux, you can check!), less boilerplate (the actions are self dispatching and it's very quick to write new ones) and the guarantee that my typescript definitions stay up to date (I don't believe in external definitions except for things like react where you can be fairly sure various people will keep it up to date)
On the other hand I have no need for many things redux and its various extensions provide.

less boilerplate (the actions are self dispatching and it's very quick to write new ones)

FWIW, from http://redux.js.org/docs/recipes/ReducingBoilerplate.html:

Actions are plain objects describing what happened in the app, and serve as the sole way to describe an intention to mutate the data. It’s important that actions being objects you have to dispatch is not boilerplate, but one of the fundamental design choices of Redux.

There are frameworks claiming to be similar to Flux, but without a concept of action objects. In terms of being predictable, this is a step backwards from Flux or Redux. If there are no serializable plain object actions, it is impossible to record and replay user sessions, or to implement hot reloading with time travel. If you’d rather modify data directly, you don’t need Redux.

One interesting competing project that is TypeScript friendly is https://github.com/ngrx/store
It is not fully Redux-compatible but people like using it with Angular.

@gaearon I know why you did it, I'm not saying "redux could have less boilerplate". I've just chosen a different set of tradeoffs :p

https://github.com/ngrx/store is using typescript but is not type-safe at all. You can dispatch anything, and you have no type hint in the update function(s).

I've just chosen a different set of tradeoffs :p

:+1:

You can dispatch anything, and you have no type hint in the update function(s).

Thanks, it seems that you are right. Would you like to bring this up with them? I wonder whether this is intentional.

Please help review the new official typings in https://github.com/reactjs/redux/pull/1413.

Here is a combination of the above ideas of type-guards and type name same as string const:
The advantage is that you only need one typeguard function which is generic and can be used across all reducers. Not sure if it works though, have not used it in real world projects :-).
type Action<TPayload> = {
	type:string,
	payload:TPayload
}

const FOO_ACTION = 'FOO_ACTION';
type FOO_ACTION = { foo:string };
const BAR_ACTION = 'BAR_ACTION';
type BAR_ACTION = { bar:number };

// This is the only type-guard function needed since it is generic
function is<TPayload>(action: Action<any>, actionName:string): action is Action<TPayload> {
	return action.type == actionName;
}

function reducer(state:string, action:Action<any>) {
	if(is<FOO_ACTION>(action, FOO_ACTION)) {
		// Type-safe access to payload
		const x:string = action.payload.foo;
		//...
		return state;
	}
	else if(is<BAR_ACTION>(action, BAR_ACTION)) {
		// Type-safe access to payload
		const x:number = action.payload.bar;
		// ...
		return state;
	}
}

My latest approach allows to eliminate boilerplate for specifying types along action type strings:
interface ActionCreator<P> {
  type: string;
  (payload: P): Action<P>;
}

function actionCreator<P>(type: string): ActionCreator<P> {
  return Object.assign(
    (payload: P) => ({type, payload}),
    {type}
  );
}

export function isType<P>(action: Action<any>, actionCreator: ActionCreator<P>): action is Action<P> {
  return action.type === actionCreator.type;
}

This way I can set up action by a single statement:
const fooAction = actionCreator<{foo: string }>('FOO_ACTION');

And use it in reducers:
const reducer = (state: State, action: Action<any>): State => {
  if (isType(action, fooAction)) {
    // action payload type is inferred to `{foo: string}`
  }

  return state;
}

I also add extra check to actionCreator function to ensure that action types are unique.

@aikoven This looks like an interesting approach. So basically the action creator function is responsible for carrying the string constant around. If you want to use redux-saga or similar and need the string constant to do take(), you can import the action-creator foo and then use foo.type to get the string constant. The only thing I don't understand is how you do this part:

I also add extra check to actionCreator function to ensure that action types are unique.

@aikoven
Importing the action creator to the reducer seemed a bit unintuitive to me. It's nice to not have to define a constant string at all, though.
How about typing the constant string with a generic instead?
interface ActionType<TPayload> extends String {}

type Action<TPayload> = {
    type: ActionType<TPayload>,
    payload: TPayload
}

interface ActionCreator<P> {
    (payload: P): Action<P>;
}

function actionCreator<TPayload>(type: ActionType<TPayload>): ActionCreator<TPayload> {
    return (payload) => ({
        type,
        payload
    });
}

export function isType<TPayload>(
    action: Action<any>,
    type: ActionType<TPayload>
): action is Action<TPayload> {
    return action.type === type;
}

The type property in the action is still just a string, but it is typed to be a generic of the type i want to guard for.
// In actions.ts
type Foo = { foo: string };

export const FOO: ActionType<Foo> = 'FOO';

export const createFoo = actionCreator<Foo>(FOO);

// In reducer.ts
const reducer = (state: State, action: Action<any>): State => {
    if (isType(action, FOO)) {

        let foo:string = action.payload.foo;
    }

    return state;
}

@jonaskello

If you want to use redux-saga or similar and need the string constant to do take(), you can import the action-creator foo and then use foo.type to get the string constant.

Exactly.

The only thing I don't understand is how you do this part:

I also add extra check to actionCreator function to ensure that action types are unique.

Simple:
const actionTypes = {};

export function actionCreator<P>(type: string): ActionCreator<P> {
  if (actionTypes[type])
    throw new Error(`Duplicate action type: ${type}`);

  actionTypes[type] = true;

  return Object.assign(
  // ...

@geon That's clever, although it still involves boilerplate to define action type. I don't see any drawbacks in importing action creators to reducers. In fact, all my action creators are simple pure functions and they encapsulate action type string and action payload type, nothing more. And both are used in reducers, so it seems fine to me.

@aikoven Thanks, that's what I guessed you meant :-). Btw, how do you handle actions that have no payload? Just setting the payload type to any does not seem like a nice solution...

@geon @aikoven @jonaskello I'm not sure if your solutions solve the nominal typing problem that I mentioned above. Basically the question is if type checking would tell apart actions with same shape? The problem is there are a lot of cases when actions with completely different purpose have the same payload shape.

@igorbt The type-guard function looks at the action.type string to tell which type the action has. So the shape should not matter.

@jonaskello you are right! I was mislead by the use-case for nominal typing illustrated here which is not quite relevant for Redux. So, thanks for pointing me in the right direction on how to simplify things. I don't have FSA actions in my app, and also I have a lot of actions that has only type with no data, so I adapted a bit from @geon's solution, so that's a more generic solution IMHO:
interface ActionType<TAction> extends String {}

interface Action {
    type: string;
}

interface FooAction extends Action {
    foo: string;
}

interface BarAction extends Action {
    bar: string;
}

function isType<T extends Action>(
    action: Action,
    type: ActionType<T>
): action is T
function isType<T extends Action>(
    action: Action,
    type: string
): action is T
{
    return action.type === type;
}

const FOO: ActionType<FooAction> = 'FOO';
const BAR: ActionType<BarAction> = 'BAR';
const BAZ = 'BAZ';

export const reducer = (state: any, action: Action): any => {
    if (isType(action, FOO)) {

        let foo = action.foo;
    }
    if (isType(action, BAR)) {

        let bar = action.bar;
        action.foo; // error
    }
    if (isType(action, BAZ)) {
        action.type; // BAZ
        action.foo; // error
    }
    return state;
}

@jonaskello

Btw, how do you handle actions that have no payload? Just setting the payload type to any does not seem like a nice solution...

I'm using void type parameter for them, although until this is resolved I have to make payload argument of resulting action creator optional:
interface ActionCreator<P> {
  type: string;
  (payload?: P): Action<P>;  // payload is optional
}

const fooAction = actionCreator<void>('FOO_ACTION');

const action = fooAction();

However, this is obviously not so type-safe. Another option would be to pass void 0 as a parameter, but I chose brevity over safety here, because I have lots of actions with no payload.

@igorbt , elegant solution. Gets rid of the nominal typing hack, the unneeded classes and the risk of being tempted to use instanceof.
As an idea, it could be possible to use the same name for the ActionType constant as for the action interface without them conflicting. The constant and interface will probably be defined in the same place if the app is modular.
I'm also thinking if it might be possible somehow in the future to replace strings with Symbols. As it stands, we need to generate some unique strings for each action type, while still having something human readable.

@aikoven Thanks, doing it the same way now  seeing the proposal for ignoring void is approved
@igorbt @use-strict I started out using the solution @geon proposed but it has the limitation that the action string no longer can be treated as a string. Eg. this code will not work:
const FOO: ActionType<FooAction> = 'FOO';
const myString:string = FOO;

The problem lies in that in JS there is a difference between String and string an TS can only extend String not string. This will become a problem if you want to send your action.type string to another API such as redux-saga. Becuase that API will expect a string but you will be sending a String. Of course you can type-cast in those cases but in the end I went with the solution @aikoven proposed because it avoids this problem and also it save one line of code for each action since the string is baked into the action creator function itself.

@use-strict Usage of Symbol for actions has been discussed many times and it is not a good idea because Symbolis not serializable. So if you later want to send your actions somewhere else (local storeage, http etc.) it will not work. So we should use strings. The solution @aikoven suggested will work almost the same way as Symbols anyway. You refer to the action creator function everywhere instead of the string itself. So the action creator function itself becomes the symbol. If you want, you could modify the actionCreator() function in his solution to generate unique strings automatically since you will never refer to the strings directly in the code.

One part of @aikoven solution I had a hard time understanding was this:
interface ActionCreator<P> {
  type: string;
  (payload: P): Action<P>;
}

To clarify: It looks like this type specifies an object but it actually specifies a single function. He is using the trick that functions in JS are objects. So you can attach a property to a function. So this type specifies a function of type (payload: P) => Action<P> but it also says that this function can have an attached property called "type". I find this TS syntax to be quite funky but it works.

Actually I think the idea of attaching the string to the action creator function has merit outside TS. Here is a plain ES6 example of doing the same thing which may be easier to understand (not tested it but I think it works :-)). Notice that we no longer need to declare a separate string constant because the string is baked into the action creator function:
// In actions.js
function fooAction(foo:string) {
	return {
		foo: foo;
	}
}
fooAction.type = 'FOO';

// In reducer.js
import {fooAction} from './actions';

function(state, action) {
	if(action.type === fooAction.type) {
	 	// Do foo action stuff
	}
}

Maybe this could be added as a reducing boilerplate recipe in the docs.

@aikoven @jonaskello I like your solution more and more. It took me some time to understand it's advantages but now I will give it a try. I'll also switch to FSA.
@jonaskello i think in your ES6 example you should also use actionCreator factory otherwise it will not work.

After playing with the great suggestions here (mainly @jonaskello's) I found two small drawbacks that I wanted to overcome:

It is a bit awkward to use action creators in the reducers. Feels strange with the camel-casing, no type highlighting and just having them there in general.
The need for a action creator in the first place. I have a mostly server driven application where many actions are instantiated on the server and the type definitions are generated.

Here is my suggestion:
export class ConnectAction {
    static type = "Connect";
    host: string;
}

// Variant1: less boilerplate to create
export const connect1 = common.createAction(ConnectAction)

// Variatn2: less boilerplate to call
export const connect2 = common.createActionFunc(ConnectAction, (host: string) => ({ host: host}))

Invoking action creators:
connect1({ host: 'localhost'})
connect2('localhost');

Reducer:
const reducer = (state: any = {}, action: Action) => {
    if (is(action, ConnectAction)) {
        console.log('We are currently connecting to: ' + action.host);
        return state;
    } else {
        return state;
    }
}

The common/generic stuff:
export interface ActionClass<TAction extends Action> {
    type: string;
    new (): TAction;
}

export interface Action {
    type?: string;
}

export function createAction<TAction extends Action>(actionClass: ActionClass<TAction>): (payload: TAction) => TAction {
    return (arg: TAction) => {
        arg.type = actionClass.type;
        return arg;
    };
}

export function createActionFunc<TAction extends Action, TFactory extends (...args: any[]) => TAction>(
    actionClass: ActionClass<TAction>,
    actionFactory: TFactory): TFactory {
    return <any>((...args: any[]): any => {
        var action = actionFactory(args);
        action.type = actionClass.type;
        return action;
    });
}

export function is<P extends Action>(action: Action, actionClass: ActionClass<P>): action is P {
    return action.type === actionClass.type;
}

The drawbacks with this solution are:

Unconventional usage of classes - they are never instantiated.
Have to make the type property i the Actions interface optional (this is super minor to be).
It is cumbersome to add optional properties to the actions since they are classes (have to add an additional interface).

Even though the new drawbacks this solution works better for my current use cases. Also I don't use the Flux Standard Action style but I bet one can make such a variant with my suggestion.

Note that we have added some typing files in 3.5.x.
If those aren’t as helpful feel free to raise an issue to discuss how they can be improved.

@Cooke see https://github.com/reactjs/redux/issues/992#issuecomment-191219795. I don't see anything wrong with having action creators in reducers because they only encapsulate action type string and payload shape. Of course there's also action instantiation logic, but there's no difference with classes: they too contain its own type info along with construction logic.

@geon In regards to the "String vs. string" problem", how about:
export interface _ActionType<T>{}
export type ActionType<T> = string & _ActionType<T>

// important to use _ActionType here
export function isAction<T extends Action>(action: Action, type: _ActionType<T>): action is T;
export function isAction<T extends Action>(action: Action, type: string): action is T {
    return action.type === type
}

You can use this as before but it will be a regular string and not a String.

This approach is working good...

Get typed actions and payload to dispatch.
Redux gets clean plain objects
Reducers gets typed action types, and typed payloads.

First setup enums..
export enum ActionTypes { TYPE_SELECTED }

create your commands...

export class ActionSelectedCommand  {
  constructor(public actionitem: any) {
  }
}

Create your function to call when dispatching (notice I am creating a standard object that in a sense serializes my command object).
So every action will always have a type and a payload.
export function ActionSelected(actionItem): any {
  return {
    type: ActionTypes.TYPE_SELECTED,
    payload: JSON.stringify(new ActionSelectedCommand(actionItem))
  };
}

Then on your reducer...

  if (!state)
    state = new NewStore();

  let type: actions.ActionTypes = <actions.ActionTypes>action.type;  -- constant action type :)

  switch (type) {
    case actions.ActionTypes.TYPE_SELECTED: {  -- more constact action type
      var warmAndFuzzyPayLoad = <actions.ActionSelectedCommand>JSON.parse(action.payload)
      -- Then you deserialize back to your action command with all your parameters type set.
      return state;
    }
    default:
      return state;
  }

Then dispatch away...
store.dispatch(actions.ActionSelected("Tight Actions"));
So far this seems to be working well.
It forces to keep the action commands very simple because any recursion or self referencing will blow this up.
I like the idea of keeping the redux store type free.  This allows the ability to have flexibility in and out of the bus.
Cheers

I think that discriminated union types which are arriving in TypeScript 2.0 should be a good solution for this issue.

My dream action support would be something like elm or scala.js where reducer is powered by pattern matching. But it seems typescript would not have pattern matching in the near future :(

Another version with plain objects in reducer, based mainly on @Cooke.
It allows to inline action payload fields and omit explicit Action definition.
ActionTypes here are used as generic action creators.
export interface Action {
    type?: string;
}
export class ActionType<T extends Action>{
    type: string;
    constructor(type: string) {
        this.type=type;
    }
    new(t: T):T {
        t.type=this.type;
        return t;
    }
}

export function isAction<T extends Action>(action: Action, type: ActionType<T>|string): action is T {
    if (typeof type === 'string') {
        return action.type==type;
    } else if (type instanceof ActionType) {
        return action.type === type.type;
    }
    return false;
}

const FOO: ActionType<{foo: string, foo2: string}> = new ActionType<any>('FOO');
interface BarAction extends Action {
    bar: string;
}
const BAR: ActionType<BarAction> = new ActionType<BarAction>('BAR');

in reducer:
export default function reducer(state = [], action:Action) {
    if (isAction(action, FOO)) {
        action.foo // have access
        return state;
    } else if (isAction(action, BAR)) {
        action.bar;
        return state;
    } else
        return state;
}

create new action like this
FOO.new({foo: 'foo'}) // error, foo2 is required
FOO.new({foo: 'foo', foo2: 'foo'}) // OK

// dispatch it like this
dispatch(FOO.new({foo: 'foo', foo2: 'foo'}));

You have type safe payload and don't have to use designated task creator.
You still can create actions old way. Main drawback is that type is not required in Action interface.

Here's a new version based on the proposals by @aikoven, @jonaskello and inspired on redux-actions.
The goal is to to address these specific scenarios:

Type safety for state, actions and payload
Allow sharing of type safe state and local variables for all handlers inside reducer functions
Preserve standard action creator function syntax to allow for logic, thunks, etc.
Reduce switch-case boilerplate in reducers

Here it goes, let me know if you see any major flaws!
// FSA Compliant action
interface Action<P> {
    type: string,
    payload?: P,
    error?: boolean,
    meta?: any
}

interface Todo {
    text: string
}

// Handle actions "inspired" by redux-actions
// Only returns the to allow sharing type-safe state in the reducer function
export const DEFAULT = "DEFAULT";
export function handleActions<T>(
    action: Action<any>,
    handlers: { [type: string]: { (action: Action<any>): T } },
    defaultState: T): T {

    let keys = Object.keys(handlers);

    // Call each handler
    for (let i = 0; i < keys.length; i++) {
        if (handlers[action.type]) {
            // Execute the function passing the action and return its value
            return handlers[action.type](action);
        }
    }

    // If no handlers matched the type, execute the DEFAULT handler
    if (handlers[DEFAULT]) {
        return handlers[DEFAULT](action);
    }

    // If DEFAULT not declared, return the state from the parameter
    return defaultState;
}

export const ADD_TODO = "ADD_TODO";
// Declare the type for the payload
export type ADD_TODO = Action<string>
// Standard action creator pattern with type safe return value
export const addTodo = (text: string): ADD_TODO => {
    // Allows for some complex logic, async behavior, thunks, etc.

    return {
        type: ADD_TODO,
        payload: text,
        meta: {
            foo: "Bar"
        }
    }
}

export const DELETE_TODO = "DELETE_TODO";
export type DELETE_TODO = Action<number>
export const deleteTodo = (index: number): DELETE_TODO => {
    // Some complex logic, async behavior, thunks, etc.

    return {
        type: DELETE_TODO,
        payload: index,
    }
}

// Standard pattern for creating reducers
// Type safety for state and return value, shared for all handlers
export const todoReducer = function (
    state: Todo[] = [],
    action: Action<any>): Todo[] {
    // Local variables can be declared and shared by all handlers
    let foo = action.meta && action.meta.foo;

    // Type safety for return value of state
    return handleActions<Todo[]>(action, {
        // Less boilerplate by removing the 'return' and 'break' statements
        // Payload is a string
        [ADD_TODO]: ({payload}: ADD_TODO) => [...state, { text: payload }],
        // Payload is a number
        [DELETE_TODO]: ({payload}: DELETE_TODO) =>
            [...state.slice(0, payload), ...state.slice(payload + 1)],
        // For more complex actions, expand function
        [DEFAULT]: ({payload}) => {
            // Can handle other operations that don't depend on type
            if (foo) {
                console.log(foo);
            };
            return state;
        }
    },
        // In case DEFAULT is not implemented, return the default state
        state);
}

// Dispatch in the context of a connected component
addTodo("Foo");
deleteTodo(0);

@Agalla81 I like this design. I'm confused about the handleActions implementation though - what's the loop for? Wouldn't the following work:
    return handlers[action.type] ? handlers[action.type](action)
        : handlers[DEFAULT] ? handlers[DEFAULT](action)
        : defaultState;

@alexfoxgill You're correct, the loop was unnecessary. This has been updated based on your suggestion for the handleAction implementation, thanks for noticing.
I like the createReducer approach but it may collide with one of the items that I wanted to address:
"2. Allow sharing of type safe state and local variables for all handlers inside reducer functions".

Type Safe state is indeed shared with the "double" arrow function "=> s =>".
But how can shared local variables be defined when using createReducer?
In some scenarios, I find it useful to define those if there's common logic that can be re-used by multiple action handlers inside the reducer.

@Agalla81 I guess that's a fair point, though I've not encountered a time when I've needed that common logic within the reducer definition itself (normally it's in other functions)

@alexfoxgill here's an example from Redux's documentation that shows such a case scenario, by declaring a "post" local variable that can be reused in different action handlers.
Source: http://redux.js.org/docs/recipes/reducers/UpdatingNormalizedData.html
// reducers/posts.js
function addComment(state, action) {
    const {payload} = action;
    const {postId, commentId} = payload;

    // Look up the correct post, to simplify the rest of the code
    const post = state[postId];

    return {
        ...state,
        // Update our Post object with a new "comments" array
        [postId] : {
             ...post,
             comments : post.comments.concat(commentId)
        }
    };
}

Just published a package implementing my above approach:
https://github.com/aikoven/redux-typescript-actions

I stumbled upon this thread when trying to use concrete classes for actions like @nickknw to enforce type safety and redux reasonably yelled at me for not using plain objects.
I realized that with with Typescript 2.0, @frankwallis' premonition has come true, so I figured I would update with an example for anyone else who ends up here.
/* define the waxing actions and create a type alias which can be any of them */
interface WaxOn
{
    type: "WaxOn";
    id: number;
    waxBrand: string;
}

function createWaxOnAction(id: number, waxBrand: string): WaxOn
{
    return { type: "WaxOn", id, waxBrand };
}

interface WaxOff
{
    type: "WaxOff";
    id: number;
    spongeBrand: string;
}

function createWaxOffAction(id: number, spongeBrand: string): WaxOff
{
    return { type: "WaxOff", id, spongeBrand };
}

type AnyWaxingAction = WaxOn | WaxOff;

/* define the dodging actions and create a type alias which can be any of them */
interface Bob
{
    type: "Bob";
    id: number;
    bobDirection: number[];
}

function createBobAction(id: number, bobDirection: number[]): Bob
{
    return { type: "Bob", id, bobDirection };
}

interface Weave
{
    type: "Weave";
    id: number;
    weaveDirection: number[];
}

function createWeaveAction(id: number, weaveDirection: number[]): Weave
{
    return { type: "Weave", id, weaveDirection };
}

type AnyDodgeAction = Bob| Weave;

type AnyActionAtAll = AnyWaxingAction | AnyDodgeAction;
// action must implement one of the Action interfaces or tsc will yell at you
const reducer = (state: State, action: AnyActionAtAll) =>
{
    switch(action.type)
    {
        case "WaxOn":
            // Will only let you access id and waxBrand
        case "WaxOff":
            // Will only let you access id and spongeBrand
        case "Bob":
            // Will only let you access id and bobDirection
        case "Weave":
            // Will only let you access id and weaveDirection
        default:
            return state;
    }
}

If you accidentally name two actions with the same type string, typescript wont necessarily yell at you, but in the switch-case for that string, typescript will only let you access the members which both interfaces have in common.

@awesson You might want to assert that action is of type never in the default case in the switch statement. This way you can be sure that all actions are handled and you don't forget to add more cases to the switch if you create new actions. See this page under the "Exhaustive Checks" section for more info.

Thanks @jonaskello. That's a good point.
I updated my example, but really it's probably better to just look at the example you linked. (I don't know how I missed that.)
One note about the exhaustive check is that if you are just starting to write actions for a new module following this organization and you only have 1 action so far, the type alias wont be a union and so the exhaustive check will always fail.

I have been looking at different solutions for full typing support (state and actions), and I have found https://gist.github.com/japsu/d33f2b210f41de0e24ae47cf8db6a5df + @awesson's solution to be a really good combination

After playing around with the different alternatives I settled with the following approach https://github.com/Cooke/redux-ts-simple

You can use union types but you can also use a big typed action object.
// Before

{
    type: "UserLoaded",
    payload: {
        user: { id: 4 }
    }
}

// After

{
    type: "UserLoaded",
    userLoaded: {
        user: { id: 4 }
    }
}

In the first case, there are lots of different action objects so you need a union type.
interface UserLoaded {
    type: "UserLoaded",        // redundant
    payload: {
        user: User;
    };
}

type MyAction = UserLoaded | OtherAction

In the second case, there is just one action type with lots of payload keys.
interface UserLoaded {
    user: User;
}

interface MyAction {
    type: string;
    userLoaded?: UserLoaded;
    otherAction?: OtherAction;
}

You can reduce by matching the type by string.
function userById(state = {}, action: MyAction) {
    if (action.type == "UserLoaded") {
        // action.userLoaded.user
    }
}

You can also check presence of payload key.
function userById(state = {}, action: MyAction) {
    if (action.userLoaded) {
        // action.userLoaded.user
    }
}

If you use presence, you don't rely on type anymore for actual reducing so you don't need to worry if a someone used the same name in another part of your project. You can also nest action payloads relating to a specific widget or domain inside a parent action object that includes context.
enum Field {
    Title,
    Body,
}

interface TextChange {
    field: Field;
    newText: string;
}

interface Submit {

}

interface NewPostForm {
    pageId: string;
    textChange?: TextChange;
    submit?: Submit;
}

interface MyAction {
    type: string;
    newPostForm?: NewPostForm;
}

If you really love union-ing actions from sub modules you can still use interface inheritance.
interface UserLoaded {
    user: User;
}

interface UserAction {
    userLoaded?: UserLoaded;
}

interface MyAction extends UserAction {
    type: string;
}

So yeah, it plays well with JSON serialization, existing redux tooling, and it's a nice balance between encapsulating some parts while still allowing cross-cutting actions.

I guess everyone has already mentioned most of the solutions. My two cents on this topic, I just wanna emphasize about @aikoven approach. Even though I found this topic just now, my solution is very close to his.
Here how I've done it, I tried to remove all the boilerplate as much as possible:
feature-x.actions.ts
import { defineAction, defineSymbolAction } from 'redux-typed-actions';
import { ItemX } from './feature-x.types';

// For this action we don't have any payload
export const FeatureXLoadAction = defineAction('[Feature X] Load');

// Let's have a payload, this action will carry a payload with an array of ItemX type
export const FeatureXLoadSuccessAction = defineAction<ItemX[]>('[Feature X] Load Success');

// Let's have a symbol action
export const FeatureXDummySymbolAction = defineSymbolAction<ItemX[]>('[Feature X] Dummy Started');

feature-x.component.ts
import { ItemX } from './feature-x.types';
import { FeatureXLoadAction, FeatureXLoadSuccessAction } from '../feature-x.actions';
...
store.dispatch(FeatureXLoadAction.get());

// or in epics or side effects
const payload: ItemX[] = [{ title: 'item 1' }, { title: 'item 2' }];
store.dispatch(FeatureXLoadSuccessAction.get(payload));
// And a more strict check for payload param
store.dispatch(FeatureXLoadSuccessAction.strictGet(payload));

feature-x.reducers.ts
import { PlainAction } from 'redux-typed-actions';
import { ItemX } from './feature-x.types';
import { FeatureXLoadAction, FeatureXLoadSuccessAction } from '../feature-x.actions';

export interface ItemXState {
  items: ItemX[];
  loading: boolean;
}

...
export function reducer(state: ItemXState = InitialState, action: PlainAction): ItemXState {
  if (FeatureXLoadAction.is(action)) {
    // Within this branch our action variable has the right typings
    return {
      ...state,
      loading: true,
    }
  } else if (FeatureXLoadSuccessAction.is(action)) {
    return {
      ...state,
      loading: false,
      items: action.payload, // <- Here we are checking types strongly :)
    }
  } else {
    return state;
  }
}

Here a live example

@jonaskello i liked your comment about symbols. You mention:
If you want, you could modify the actionCreator() function in his solution to generate unique strings automatically since you will never refer to the strings directly in the code.
if i am not wrong the devtools will display these strings? so we still need to generate unique string that make sense related to the real action and not just uuids.
So i think what @aikoven propose to don't have this problem is not that bad.
export function actionCreator<P>(type: string): ActionCreator<P> {   if (actionTypes[type])     throw new Error('Duplicate action type: ${type}');

Or a better solution would be to check the process.env.NODE_ENV and if it's development warn the developer and if it's production just generate a random hash and attach it to the action type value to make it unique. This way it will never fail in prod.

@aminpaks i think devtool with real action name in prod is usefull.
https://medium.com/@zalmoxis/using-redux-devtools-in-production-4c5b56c5600f
What if we want the end-users to help the debugging

@nasreddineskandrani I never said we should remove the initial action type. I meant let's add a hash to the end so we'll have an unique action.

one of the dev in this thread mention this:
.... I have a mostly server driven application where many actions are instantiated on the server and the type definitions are generated.
with a dynamic type strategy take in count that your lib need the exact same hash in 2 differents servers for a specific action and not a random one.

I recently added a React example using redux-typed-actions to demonstrate how this strategy can help to improve productivity and will remove all boilerplates.
Take a look here.


Implement storage power evolution in simulations for honest participants

Implement the ability to evolve the storage power across honest participants over the course of a simulation. The changes introduce primitives to allow doing this and reflect the changes across the tests using a uniformed fixed storage power generator.
The adversary storage power evolution is not yet implemented and left to future work in favour of reducing the number of lines changed.
Add two tests that exercise increase and decrease of storage power over sync and async message passing:

Sudden increase of storage power results in the corresponding group of nodes to dominate consensus as expected.

Gradual decrease of storage power results in loss of dominance among the corresponding group.

Fixes #114
Rebased on top of #187; review that first.

Could you change this PR base to #184 so it's easier to review the diff proposed here?


Default commit message?

Hey!
I'm looking to merge pull requests while using the default merge message. Is there a way to call client.PullRequests.Merge without supplying a commit message so it defaults? I don't want to include an empty string for fear that it'll cause empty or otherwise undesired commit messages. Is passing "" the ticket to defaulting?
Thanks :)

Not sure what will happen if you pass an empty string in that case. Try in a test repo and find out? :)

Hm! Turns out if you do send something, it will just stick it at the bottom of your automatic commit message:
commit 4255f7ec0dcda04efe40d863d55650793468a767
Merge: fc4d671 a8f4633
Author: Parker Moore<EMAIL_ADDRESS>Date:   Wed Mar 11 01:17:55 2015 -0700

    Merge pull request #20 from parkr/fix-release

    Merge pull request 20


Update asset create in notification

@MarkRiddoch  Can we please cherry-pick the commits, instead of merging develop into 1.7.0RC?

We can test and merge https://github.com/foglamp/foglamp-notify-asset/pull/20 and close this!

@MarkRiddoch Can we please cherry-pick the commits, instead of merging develop into 1.7.0RC?

Sure no problem with that.


Don't use brew for llvm path

Currently, the setup.py file uses brew to find llvm: https://github.com/PennyLaneAI/pennylane-lightning/blob/f1a67893ed38cea27c29a4bc64a28fe1ec58e2f6/setup.py#L90
Would it be possible to remove that and use a different way?
I am the maintainer of the conda-forge distribution of pennylane-lightning and we do not use brew in our CI so I am currently unable to package pennylane-lightning for OSX.
Ref: https://github.com/conda-forge/pennylane-lightning-feedstock/pull/12
Logs: https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=552109&view=logs&jobId=9c5ef928-2cd6-52e5-dbe6-9d173a7d951b&j=9c5ef928-2cd6-52e5-dbe6-9d173a7d951b&t=20c71c51-4b27-578b-485d-06ade2de1d00

Hi @BastianZim thanks for getting in touch.
Our method for building wheels for Lightning relies explicitly on the Github Actions runners and their supported packages, of which homebrew is a relied upon toolchain provider (see here).
Since we require full knowledge of the build tooling and system for standardised runtimes performance and debugging, we may find it difficult to provide support for wheels not built within the same compiler tooling as we use for each targeted release. Is it possible for your system image to be updated to include the same brew infrastructure as we use, or potentially use the provided Github Runner images in your build process?

Hi @mlxd thanks for the explanation.
Conda-forge uses the same build environment across all of its packages to guarantee compatibility, so, unfortunately, I cannot change anything in the underlying tools. I am able to set newer compiler versions but nothing else.
From what I can see, you're just using the command to find the compiler, so would it maybe be possible to replace that with something different? If not, no worries, then I'll try to add a patch in conda-forge that switches that for a different approach.

Hey @BastianZim we currently use the brew clang to build wheels for x86 Macs. Largely the reason for this was the older MacOS 10.14/10.15 runners had insufficient C++17 and C++20 support for our builds, so we needed a more updated compiler. The MacOS 11 runners had updated compiler infrastructure and allowed us to build safely for the Arm variants. We recently ported the now deprecated MacOS 10.15 builder support to MacOS 11 runners for x86, but still rely on brew for the compilation there.
We likely won't deviate from that for some time, but we do have on our roadmap to rely entirely on the Apple toolchain for a future release on x86.  We will also need to understand the performance impact of the compiler change, so this is currently not going to happen until PennyLane Lightning v0.27.0 at the earliest, which is expected a little later in the year.
We can keep this issue open and report once this change has been made. Does that work for you?

Ahh ok – thanks for the clarification. So you first install everything with brew, and then in the build script, use brew to identify where everything was installed?
If I install the necessary toolchain myself and then add a patch to the llvmpath = subprocess.check_output(["brew", "--prefix", "llvm"]).decode().strip() line I should be able to rely on our own compilers and still be able to run everything, correct?

We can keep this issue open and report once this change has been made. Does that work for you?

Yes that would be great, thank you!

Ahh ok – thanks for the clarification. So you first install everything with brew, and then in the build script, use brew to identify where everything was installed?

Yes, that is right. Brew on the Github Actions runners comes preinstalled with everything, so we pull the paths in the subprocess line, and use that for the rest of the process.

If I install the necessary toolchain myself and then add a patch to the llvmpath = subprocess.check_output(["brew", "--prefix", "llvm"]).decode().strip() line I should be able to rely on our own compilers and still be able to run everything, correct?

If you strip the above line, provided your version of LLVM or GCC is modern enough it should work as expected. We are currently defaulting to clang-13 in the builds, so if possible I'd recommend to use that or newer.

Ok that's great! From my side, this is then resolved.
Happy to keep the issue open if you want to use it for tracking, otherwise I can also close it?

Thanks @BastianZim
Let's keep it open, and I can update here once the builds are updated on our side.

Hi @BastianZim we are currently looking at improving the support for the conda-forge builders you have provided. We can aim to start with this request, and see what else we need to bring the latest v0.28.0+ releases. Do you still have the time to help with maintenance on the recipe side?

Hi @mlxd that's great, thanks! Yeah happy to help out wherever I can. If you're familiar with conda-forge, also happy to add you (or anyone else) to the team.
For the overall process, removing brew and allowing us to optionally (Maybe through an env variable) provide our own third-party dependencies instead of building them together with this package during the build step would make it much easier.

Hi @BastianZim , I would like to assist you in resolving this issue. I'm not familiar with conda-forge yet, but I would like to be part of the team if that helps.
Since it appears that your problem is caused by a single line calling brew, I think the simplest thing would be to change the value of llvmpath with an environment variable, LLVM_ROOT_DIR say, as you suggested.


Details are unavailable (CS_ERR_DETAIL)

I've installed BARF but I'm not sure if it's installed correctly. I run the following code for a binary shared object file (.so), but it encounters an error while it's translating.
from barf import BARF

# Open binary file.
barf = BARF('bin/tests/test1.so')

# Print assembly instruction.
for addr, asm_instr, reil_instrs in barf.translate():
    print("0x{addr:08x} {instr}".format(addr=addr, instr=asm_instr))

    # Print REIL translation.
    for reil_instr in reil_instrs:
        print("{indent:11s} {instr}".format(indent="", instr=reil_instr))

Output:
Couldn't import dot_parser, loading of dot files will not be possible.
0x00000e98 moval r4, r0
            str   [DWORD r0, EMPTY, DWORD r4]
            and   [DWORD r0, DWORD 0xffffffff, DWORD t1]
            bisz  [DWORD t1, EMPTY, BIT zf]
            bsh   [DWORD r0, DWORD 0xffffffe1, DWORD t2]
            and   [DWORD t2, DWORD 0x1, BIT t3]
            str   [BIT t3, EMPTY, BIT nf]
0x00000e9a bal #0x9dc
            jcc   [BIT 0x1, EMPTY, POINTER 0x9dc00]
0x00000e9c moval r0, r0
            str   [DWORD r0, EMPTY, DWORD r0]
            and   [DWORD r0, DWORD 0xffffffff, DWORD t4]
            bisz  [DWORD t4, EMPTY, BIT zf]
            bsh   [DWORD r0, DWORD 0xffffffe1, DWORD t5]
            and   [DWORD t5, DWORD 0x1, BIT t6]
            str   [BIT t6, EMPTY, BIT nf]
0x00000e9e bal #0xfc0
            jcc   [BIT 0x1, EMPTY, POINTER 0xfc000]
Traceback (most recent call last):
  File "/home/.../main.py", line 15, in <module>
    for addr, asm_instr, reil_instrs in barf.translate():
  File "/usr/local/lib/python2.7/dist-packages/barf-0.2-py2.7.egg/barf/barf.py", line 195, in translate
    for addr, asm, _ in self.disassemble(start_addr, end_addr):
  File "/usr/local/lib/python2.7/dist-packages/barf-0.2-py2.7.egg/barf/barf.py", line 217, in    disassemble
    asm = self.disassembler.disassemble(self.text_section[start:end], curr_addr)
  File "/usr/local/lib/python2.7/dist-packages/barf-0.2-py2.7.egg/barf/arch /arm/armdisassembler.py", line 203, in disassemble
    instr = self._cs_translate_insn(disasm)
  File "/usr/local/lib/python2.7/dist-packages/barf-0.2-py2.7.egg/barf/arch/arm/armdisassembler.py", line 348, in _cs_translate_insn
    operands = [self.__cs_translate_operand(op, cs_insn) for op in cs_insn.operands]
  File "/usr/lib/python2.7/dist-packages/capstone/__init__.py", line 541, in __getattr__
    raise CsError(CS_ERR_DETAIL)
 capstone.CsError: Details are unavailable (CS_ERR_DETAIL)

Process finished with exit code 1

However, BARF runs smoothly with no problems on the toys supplied in the repo.
More Info:

The binary is in ARM32, mode:ARM
pip list | grep capstone -> capstone (3.0.4)
python-capstone 3.0.4 is installed
libcapstone3 and libcapstone-dev are installed
PyBFD is ok.

2016-07-12 13:25 GMT+02:00 Ali Reza Barkhordari<EMAIL_ADDRESS>
I've installed BARF but I'm not sure if it's installed correctly. I run
the following code for a binary shared object file (.so), but it
encounters an error while it's translating.
from barf import BARF
Open binary file.
barf = BARF('bin/tests/test1.so')
Print assembly instruction.
for addr, asm_instr, reil_instrs in barf.translate():
print("0x{addr:08x} {instr}".format(addr=addr, instr=asm_instr))
# Print REIL translation.
for reil_instr in reil_instrs:
    print("{indent:11s} {instr}".format(indent="", instr=reil_instr))

Output:
Couldn't import dot_parser, loading of dot files will not be possible.
0x00000e98 moval r4, r0
str   [DWORD r0, EMPTY, DWORD r4]
and   [DWORD r0, DWORD 0xffffffff, DWORD t1]
bisz  [DWORD t1, EMPTY, BIT zf]
bsh   [DWORD r0, DWORD 0xffffffe1, DWORD t2]
and   [DWORD t2, DWORD 0x1, BIT t3]
str   [BIT t3, EMPTY, BIT nf]
0x00000e9a bal #0x9dc
jcc   [BIT 0x1, EMPTY, POINTER 0x9dc00]
0x00000e9c moval r0, r0
str   [DWORD r0, EMPTY, DWORD r0]
and   [DWORD r0, DWORD 0xffffffff, DWORD t4]
bisz  [DWORD t4, EMPTY, BIT zf]
bsh   [DWORD r0, DWORD 0xffffffe1, DWORD t5]
and   [DWORD t5, DWORD 0x1, BIT t6]
str   [BIT t6, EMPTY, BIT nf]
0x00000e9e bal #0xfc0
jcc   [BIT 0x1, EMPTY, POINTER 0xfc000]
Traceback (most recent call last):
File "/home/.../main.py", line 15, in
for addr, asm_instr, reil_instrs in barf.translate():
File "/usr/local/lib/python2.7/dist-packages/barf-0.2-py2.7.egg/barf/barf.py", line 195, in translate
for addr, asm, _ in self.disassemble(start_addr, end_addr):
File "/usr/local/lib/python2.7/dist-packages/barf-0.2-py2.7.egg/barf/barf.py", line 217, in    disassemble
asm = self.disassembler.disassemble(self.text_section[start:end], curr_addr)
File "/usr/local/lib/python2.7/dist-packages/barf-0.2-py2.7.egg/barf/arch /arm/armdisassembler.py", line 203, in disassemble
instr = self._cs_translate_insn(disasm)
File "/usr/local/lib/python2.7/dist-packages/barf-0.2-py2.7.egg/barf/arch/arm/armdisassembler.py", line 348, in _cs_translate_insn
operands = [self.__cs_translate_operand(op, cs_insn) for op in cs_insn.operands]
File "/usr/lib/python2.7/dist-packages/capstone/init.py", line 541, in getattr
raise CsError(CS_ERR_DETAIL)
capstone.CsError: Details are unavailable (CS_ERR_DETAIL)

It looks like an internal capstone error. Can you try to dissassemble using
directly capstone? (for instance:
http://www.capstone-engine.org/lang_python.html)

Process finished with exit code 1
However, BARF runs smoothly with no problems on the toys supplied in the
repo.
More Info:

The binary is in ARM32, mode:ARM
pip list | grep capstone -> capstone (3.0.4)
python-capstone 3.0.4 is installed
libcapstone3 and libcapstone-dev are installed
PyBFD is ok.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/programa-stic/barf-project/issues/33, or mute the
thread
https://github.com/notifications/unsubscribe/AAGwvlqFrHfTTPafEjckAxplz4PrwKJYks5qU3mNgaJpZM4JKSzv
.

No. I've not tried this. But I don't think so, because Hopper can disassemble it very easily, and in other side Hopper internally uses Capstone as the disassembler.
My binary is not a very large object, it's just a toy .so file for testing purposes. I attached it: test1.so.zip

Hi! There was a step missing in the setup of Capstone. Now it's fixed. I tested it with the file you included and it worked.
I added a parameter to the translate method. You can now pass the arch_mode in case it cannot extract it from the binary. The example looks like this (note that it only translates the first function):
from barf import BARF
from barf.arch import ARCH_ARM_MODE_ARM

# Open binary file.
barf = BARF('bin/tests/test1.so')

# Print assembly instruction.
for addr, asm_instr, reil_instrs in barf.translate(0x00000e98, 0x00000ed0, arch_mode=ARCH_ARM_MODE_ARM):
    print("0x{addr:08x} {instr}".format(addr=addr, instr=asm_instr))

    # Print REIL translation.
    for reil_instr in reil_instrs:
        print("{indent:11s} {instr}".format(indent="", instr=reil_instr))

The issue has been resolved so I'm closing it.


Add Create Quick Filter action

Changes
Add Create Quick Filter action that allows users to quickly type a filter of the following format: LIB* or LIB/OBJ/MBR.MBRTYPE (OBJTYPE) where each parameter is optional except the library. For parameters which are not provided, the defaults will be used.

Checklist

[x] have tested my change
[ ] updated relevant documentation
[x] Remove any/all console.logs I added
[x] eslint is not complaining
[ ] have added myself to the contributors' list in CONTRIBUTING.md
[x] for feature PRs: PR only includes one feature enhancement.

@Liam I decided to go with the symbol-text icon as it looked like a better fit (let me know if you think list-filter might still be better). Also, let me know if you think the regular expression used for parsing can be improved.

@SanjulaGanepola We are going to need a matching PR in the docs repo for this functionality too before this can be merged. Thanks!
https://github.com/halcyon-tech/docs/tree/main/docs

Created a PR for the doc updates: https://github.com/halcyon-tech/docs/pull/10


Consider ss.parallel() syntax

Currently it returns a MultiSim, but should it just return the sims instead?

This is fine, multisims are useful and adding .sims to the end is pretty easy.


ConnectionPlugin extend connection globally not working as documented

Screenshot

Description
I've setup the ConnectionPlugin as documented like:
export const schema = makeSchema({
    types: allTypes,
    outputs: {
        schema: path.join(__dirname, "../schema.graphql")
    },
    plugins: [
        connectionPlugin({
            extendConnection: {
                totalCount: { type: "Int" },
            },
            includeNodesField: true,
        }),
    ],
});

and define the connection as:
const continents = [
    { id: "africa", code: "AF", name: "Africa", demonym: "African" },
    { id: "antarctica", code: "AN", name: "Antarctica", demonym: "Antarctican" },
    { id: "asia", code: "AS", name: "Asia", demonym: "Asian" },
    { id: "australia", code: "OC", name: "Australia", demonym: "Australian" },
    { id: "europe", code: "EU", name: "Europe", demonym: "European" },
    { id: "north-america", code: "NA", name: "North America", demonym: "North American" },
    { id: "south-america", code: "SA", name: "South America", demonym: "South American" },
];

export const Continent = objectType({
    name: "Continent",
    description: "Represents a continent.",
    definition(t) {
        t.implements("Node");
        t.string("code", {
            description: "The unique code of the continent."
        });
        t.string("name", {
            description: "The name of the continent."
        });
        t.string("demonym", {
            description: "The demonym of the continent."
        });
    },
});

export const continentConnection = queryField((t) => {
    t.connectionField("continentConnection", {
        type: Continent,
        nodes: () => {
            return continents;
        },
        totalCount: () => {
            return continents.length;
        },
    });
});

but it seems not executing totalCount as it reports the value is null.
When I remove totalCount from the query the query is executed and returns the data.

I switched this weekend to using Nexus Framework (but as I expected) I see the same issue.
I've setup a simple test project at https://github.com/marceloverdijk/nexus-prisma-country-api/tree/nexus-schema-450
These lines seem never executed when requesting the totalCount field in a query.

Note when using a per-field configuration it does work.
    t.connection('continentConnection', {
      type: 'Continent',
      nodes(parent, args, ctx, info) {
        ctx.log.info('nodes(..) called!!!!!')
        return ctx.db.continent.findMany()
      },

      // totalCount(parent, args, ctx, info) {
      //   ctx.log.info('totalCount(..) called!!!!!')
      //   return ctx.db.continent.count()
      // },

      extendConnection(t) {
        t.int('totalCount', {
          resolve: (source, args, ctx) => {
            return ctx.db.continent.count()
          }
        })
      }
    })

PS: I see same behaviour for extendEdge
settings.change({
  schema: {
    connections: {
      default: {
        extendEdge: {
          totalFoo: {
            type: 'Int',
          }
        },
        includeNodesField: true,
      },
    }
  },
})

    t.connection('continentConnection', {
      type: 'Continent',
      nodes(parent, args, ctx, info) {
        ctx.log.info('nodes(..) called!!!!!')
        return ctx.db.continent.findMany()
      },
      edgeFields: {
        totalFoo(parent, args, ctx, info) {
          ctx.log.info('totalFoo(..) called!!!!!')
          return ctx.db.continent.count()
        },
      },

totalFoo just returns null in the playground and the totalFoo method was not called.
Type safety wise everything seems to be ok.
I mean adding extendEdge configuration (without the totalFoo method) gives a compile error. After adding the compile error is gone, but is seems just not executed.

second this.

Thx @ccincotti3 for confirming this as well; at least I'm not the only one.
Hopefully this will get some attention and can be fixed in the future.

I tried too to set extendConnection.totalCount globally, and got the same result as you.
My query always resolves: totalCount: null.
Any updates on this ?

I have the same issue as well, sounds like whenever nodes is set instead of resolve, the extended functions are not called which will return null automatically

I believe this should be fixed by #569. The global connection field extensions were not executed at all


Review impact of asynchronous streams on existing rules

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#asynchronous-streams

This feature introduces the await foreach syntax. I'm not expecting it to have any impact outside of updating code that detects all variables declared within a scope.


Globalize.ParseInt works incorrect for big numbers

Globalize.parseInt("5000000000") returns 705032704 value that is wrong.
As I see the problem in truncate method, value | 0 operation. It returns 705032704  for<PHONE_NUMBER> value.
truncate = function( value ) {
return isNaN( value ) ? NaN : value | 0;
};

Thanks @belhunter!


Files appearing as folders in remote-ftp directory list

Regardless of file type all files are being listed as a folder and are unable to be opened/edited.  The Atom tree view is fine only the remote-ftp file list is affected.

I've uninstalled / reinstalled both remote-ftp and atom.  No difference after reinstallation.
Thanks for any help!

Any solution to this? I'm not able to create use RemoteFTP at all because of this. Files are not being synced and all the files in new projects are being treated as folders :/

When I updated to 0.9.4, it's OK.

Are people having this issue with 0.9.4?

Yea upgrading to 0.9.4 seems to fix it.

ok, upgrading to 0.9.4 may be a good route but when doing so I end up getting a cypher error.  See issue #559.  This just seems to be snowballing.  Thanks!

@tbett To stop this error from happening the ssh2 library had to be upgraded from 0.4 to 0.5. This is probably why you're having issue #559

@jimmaaay regarding your comment about the SSH library.  Is there a resolution to this issue or what configuration changes do I need to solve the cipher issues that will then allow me to upgrade remote-ftp.  Thanks!


eslint airbnb

I am using it for a long time and I believe it's the best thing. Really well designed. I believe most errors can be fixed automatically.
https://github.com/airbnb/javascript

What's different to eslint-config-rackt? I am using my esformatter which is perfectly configured to match the eslint config used, would need to test if it works fine with airbnb's config as well

It's pretty old and unsupported. It's easy to distract react-router guys ;)
airbnb is defacto standard, it's strict yet very powerful. I don't know what esformatter is, but I bet you don't need it since eslint can fixes almost everything automatically.

Oh, esformatter is the tool I use to format my code :P I prefer it over js-beautifier because it has so many configuration options. But I am sure we can change the settings to support airbnb smoothly :)

Forget about esformatter, maybe it works or not, I don't know, but you will have to run eslint before every commit anyway and eslint can fix (reformat etc.) almost everything autimatically.

Oh didnt know it supports that many auto fixes. Well we might be able to use them together anyways, simply send the PR to use airbnb :P

I am using this for some of my newer projects, but I see no advantage of switching and improving this right now. Gonna close it


DEV: Console warning on Requested Step at Connect Bank account.

If you haven’t already, check out our contributing guidelines for onboarding and email<EMAIL_ADDRESS>to request to join our Slack channel!

Actions performed:

Go to settings.
Go to Any workspace, create a new one if none exists.
Go to Connect Bank account on the Workspace main page.
Follow Connect Manual flow until Personal information step

Expected result:
No warning should be logged.
Actual Result:
Prop type warning is logged.
Workaround:
unknown
Platforms:

Which of our officially supported platforms is this issue occurring on?

[ ] iOS / native

Version Number:
Reproducible in staging?: Needs reproduction
Reproducible in production?: Needs reproduction
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos:
Warning: Failed prop type: The prop reimbursementAccountDraftis marked as required inRequestorOnfidoStep, but its value is undefined. RequestorOnfidoStep@webpack-internal:///./src/pages/ReimbursementAccount/RequestorOnfidoStep.js:76:86 withOnyx@webpack-internal:///./node_modules/react-native-onyx/dist/web.development.js:2135:73 withLocalize(Component) RequestorStep@webpack-internal:///./src/pages/ReimbursementAccount/RequestorStep.js:86:86 withOnyx@webpack-internal:///./node_modules/react-native-onyx/dist/web.development.js:2135:73 withLocalize(Component) div View<@webpack-internal:///./node_modules/@expensify/react-native-web/dist/exports/View/index.js:52:19 KeyboardAvoidingView div View<@webpack-internal:///./node_modules/@expensify/react-native-web/dist/exports/View/index.js:52:19 SafeAreaConsumer ScreenWrapper@webpack-internal:///./src/components/ScreenWrapper/index.js:64:86 withNetwork(ScreenWrapper) withOnyx@webpack-internal:///./node_modules/react-native-onyx/dist/web.de… react_devtools_backend.js:4012:25
Expensify/Expensify Issue URL:
Issue reported by: @parasharrajat
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1674044222710599
View all open jobs on GitHub

From @parasharrajat in thread

This is a dev warning and It can't be reproduced on staging as we disable those logs on staging and PROD.
IMO, we should assign some Engineer to reproduce this first and if they can't then we can close it.

Cannot reproduce anymore.


Attach external array to logical region

The realm side of this looks fine, except for the one issue I flagged.  My thinking is that the example programs ought to go in examples rather than tutorials, but I could be talked into having one array-attachment tutorial as well.

@eddy16112 The CI tests on Travis are flagging some issues that need to be cleaned up.  Here's one:

/home/travis/build/StanfordLegion/legion/runtime/legion/legion_ops.cc:14365:24: error: unused variable ‘inst_manager’ [-Werror=unused-variable]

       InstanceManager *inst_manager = manager->as_instance_manager(); ```

A second issue looks to be a problem with the cmake build - if you added a source file, it needs to be added to runtime/CMakeLists.txt as well I believe.

@streichler @eddy16112 Wherever the tests are placed I'd like them to be added to the appropriate section of the test suite (see below). All code in the Legion repo must be actively tested.
https://github.com/StanfordLegion/legion/blob/master/test.py#L39-L62

@elliottslaughter Done with the test.py. Thanks for your comments

All the examples do need to go in the 'examples' directory and not the 'tutorial' directory because 'tutorials' are exclusively reserved for things on the actual Legion webpage.
I'm concerned about some of the lines that were commented out checking for errors. We need to handle those properly.
The changes in the Legion runtime need to be made to match the Legion style:

All braces get there own line
There is a strict 80 character limit on each line
...

I managed to accidentally close this by deleting the deppart branch.  Deppart changes are in master, so this should target master now.

@eddy16112 It looks like github's textual merge of legion_ops.cc isn't good enough: https://travis-ci.org/StanfordLegion/legion/jobs/284337824
Please clean this up, and also resolve the conflict on language/src/rdir.  This is a submodule, so you need to make sure that subtree is sync'd to the same version as master (https://github.com/StanfordLegion/rdir/commit/2c0b613b6ebe990de2c890ec81d819daae5ac440) and then add/commit it to your branch.


added an option of juicesync to migrate data

Codecov Report

Merging #1148 (4a6d9e5) into main (886f8b0) will decrease coverage by 1.93%.
Report is 62 commits behind head on main.
The diff coverage is 0.00%.

:exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality.
@@            Coverage Diff             @@
##             main    #1148      +/-   ##
==========================================
- Coverage   40.75%   38.83%   -1.93%
==========================================
  Files          24       25       +1
  Lines        1644     1970     +326
==========================================
+ Hits          670      765      +95
- Misses        902     1103     +201
- Partials       72      102      +30

Files Changed
Coverage Δ

pkg/local-storage/utils/sshkeys.go
0.00% <0.00%> (ø)

... and 5 files with indirect coverage changes
:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more


Add svgrepo credits to README

Credits
*******

Logo vector and icon by `SVG Repo <https://www.svgrepo.com>`_.

Done in v0.7.2-pre.1


Run Service.vi does not chain registration errors properly

When Run Service.vi fails to register with the discovery service, it doesn't display an error until you click the STOP button.
AB#2270486
Link added manually by dixonjoel

In addition to errors encountered during registration with Discovery Service, Run Service.vi also mishandles cases like the user reporting an error in a fundamental plugin VI such as Get Measurement Details.vi.  We should make effort to address all these types of errors holistically and robustly.


Changed maximum length of shortname to 25 characters.

Resolves Issue #148.

Looks good and the changes will be deployed later today! Thanks for the contribution!

Your changes are live now! Thanks @tsilvers for the contribution!


assignment not working

code not running and or giving any output and my words are all red instead of blue
Version: 1.87.2
Commit: 863d2581ecda6849923a2118d93a088b0745d9d6
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/<IP_ADDRESS> Safari/537.36
Embedder: codespaces

This issue has been closed automatically because it needs more information and has not had recent activity. See also our issue reporting guidelines.
Happy Coding!


Add Travis-CI for macOS

Travis CI says: "Python builds are not available on the OSX environment."
Build fails: https://travis-ci.org/jbcoe/C_API_generation/jobs/154790915


⚠ Bofrost.be has degraded performance

In cf493a4, Bofrost.be (https://www.bofrost.be) experienced degraded performance:

HTTP code: 200
Response time: 1707 ms

Resolved: Bofrost.be performance has improved in a598818.


Display person consents when merging

This fixes #2370.

@elichad sure. I will work on this later this week.

Great, thanks.
Another idea that came out of the discussion was that we could send an email to the merged person, letting them know that their records have been merged and that they should check everything is okay (consents and the rest of their info). I'll make a separate issue for that as I think it fits better into the email automation project.

This is WIP and may require updated tests.

@elichad Ready for your re-review.


Handle edges in BrentMin.

Brent mentions explicitly that the edges should not be evaluated in general, but I think it could be useful so I included it. You can exclude it by setting evaluate_bounds=false.

ref https://github.com/JuliaNLSolvers/Optim.jl/issues/828


Playground misconfigured, fails with: OSStatus error:[-50]

The playground file is missing the Contents.swift file, as of commit  8f39d72.  Renaming Section-1.swift to Contents.swift fixes that, but it then fails (all writes appear to fail) with the errors:
OSStatus error:[-50] One or more parameters passed to a function were not valid.
OSStatus error:[-50] One or more parameters passed to a function were not valid.
OSStatus error:[-50] One or more parameters passed to a function were not valid.
error: One or more parameters passed to a function were not valid.
OSStatus error:[-50] One or more parameters passed to a function were not valid.
OSStatus error:[-50] One or more parameters passed to a function were not valid.
[]

These -50 errors are consistent with #290, and may be symptomatic of a larger problem.

Playground cannot have entitlements. So playground isn't appropriate for examples


Auto-generation of content index pages.

Basically allows content writers to focus on writing content and less on maintaining index pages. Could be a jekyll plugin or something built into the CMS...

This is done except for a couple small details, which are covered by issues #269 and #276 so I'm going to close it.


Make goosehints jinja templated

Easier to include files like README.md & CONTRIBUTING.md

fixed the formatting by running ruff

@salman1993 a bit late to mention - but this is genius BTW ! love it


Add changelog for v0.20.9

Description of changes:
Add changelog for patch release v0.20.9
Commits:
https://github.com/aws/eks-anywhere-build-tooling/commits/release-0.20/?since=2024-10-23&until=2024-11-08
Testing (if applicable):
make -C docs build

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

/cherry-pick release-0.20

/cherry-pick release-0.19

/unhold


Revert "Bump theme to 0.1.16 and update Sentry integration"

Reverts iterative/cml.dev#326

https://github.com/iterative/cml.dev/pull/329 should fix.


Replicate can specify blocks to copy

Signed-off-by: Ben Ye<EMAIL_ADDRESS>

[x] I added CHANGELOG entry for this change.
[ ] Change is not relevant to the end user.

Changes
Fixes #2713
Added a repeated flag --id to specify the blocks to replicate.

Verification

@bwplotka Updated, please take a look again!

Updated again.

LGTM  rebase only.

Rebased, PTAL

Done. PTAL again.

Just rebased this pr. PTAL again, thanks!

I will merge this since there are already two approvals!


"No" option for feedback popup

I really love the editor, but when you ask: "Would you like to give feedback?" and the options are "Take the survey" and "Remind me later" I just.. Please stop doing this, make a button "No"; if this were a conversation we would never talk again.
Then I found out you have to use Twitter; why ask at all? People who tweet will do so regardless. Keep up the great work, you guys are awesome!

A few months ago, when we introduced the new UI for notifications, we stopped showing all the Don't show again options as buttons. Instead they are now available in the gear/settings icon on the same notification.

Click on that, and you will get the Don't show again option.


Add News article

Add this link to articles
https://www.theblock.co/post/263704/vega-protocol-unveils-decentralized-perpetuals-on-trading-blockchain
and it should show up on the homepage as well


feat(kamelet): Add Flow support for Kamelets

Changes
This commit adds basic support for Kamelets canvas flow.
Notes
There are still pending topics that will be handled in upcoming pull requests, such as:

Dependency array management
Metadata configuration (f.i. Icon, Title, Annotations, and labels)

Screenshots:
Example is taken from here
Canvas

Source code

Relates to: https://github.com/KaotoIO/kaoto-next/issues/110

linked to issue #110


source_id registration of BARPA-R1-NN

label
BARPA-R1-NN
label_extended
Bureau of Meteorology Atmospheric Regional Projections for Australia (BARPA) Regional Climate Model version 1 with Newtonian nudging
source_id
BARPA-R1-NN
source_type
ARCM
release_year
2022
activity_participation
DD
institution_id
BOM
further_info_url
http://www.bom.gov.au/research/publications/researchreports/BRR-069.pdf
What license do you choose?
CC BY 4.0

Thank you, @chunhsusu
I wonder if you you want to make explicit the meaning of the "-R" in the label extended. We have in the simulation status also BARRA-R2 and BARRA-RE2 models. Do these regional reanalyses meet the CORDEX protocol? i.e are you planning to register them as well? Maybe we borrowed too much info from the original source for CORDEX-AUS (https://opus.nci.org.au/display/CMIP/CORDEX-CMIP6+datasets)

Thanks @jesusff
I can see the confusion and would like to make the following modifications to the original request:

source_id = BARPA-R1-NN   (NB: the "-NN" follows the new CORDEX final spec)
source = Bureau of Meteorology Atmospheric Regional Projections for Australia Regional Climate Model version 1 with Newtonian nudging   (NB: the "-R1" refers to RCM version 1)
label = BARPA-R1-NN  (as with the source_id)

There is no plan to register or submit our reanalysis BARRAs to CORDEX.
Let me know if further changes are needed.

OK, thank you.
I updated the original post and also the simulation status table

/register
This one was pending and looks good


Let JSON node attempt to parse buffer if it contains a valid string

[x] Bugfix (non-breaking change which fixes an issue)
[x] New feature (non-breaking change which adds functionality)

Proposed changes
Currently the JSON parse node ignores (and drops) any buffers it sees - This PR changes that behaviour to attempt to parse them as if they contain a string... (and then fails if not).
Another option is to only do this when set in always "convert to javascript object" mode. Though if we don't make that clear I'm sure someone will trip up and wonder why the difference at some point.
Checklist

[x] I have read the contribution guidelines
[x] For non-bugfix PRs, I have discussed this change on the forum/slack team.
[x] I have run grunt to verify the unit tests pass
[x] I have added suitable unit tests to cover the new/changed functionality

Coverage decreased (-0.007%) to 67.389% when pulling 6ae42eb787d81104709bbd5d073e4f82b5aaa854 on Json-try-parse-buffer into 7cd3e49f04f30b8c23a89fe08d6c984b68ce7be8 on dev.


feat: add string functions in a string module

Continue work on #217
closes #3238

@aljazerzen @eitsupi @vanillajonathan @richb-hanover Following this comment. Sorry to ping you but since you are main contributors on this repo, your opinion matters for the name of the module that would contain main functions on strings
I went with str (so usage would be str.upper, str.ends_with). But we could go with string (not a huge fan since it just adds more characters for nothing) or text (maybe more enduser friendly I don't know)
Thank you 🙏

Thanks for mentioning me (and thanks for your great works!).
I don't feel uncomfortable with str because I think the abbreviation str is pretty common, but string might be better for sure.

The substring function is interesting, perhaps it could be used for indexing and slicing with brackets #1811

Ok I'll change for string you're already a majority 😄 This name can always be changed later

EDIT: done! @max-sixty do you agree with this last change? If yes I think we're good to merge

Great!

Thanks @PrettyWood ! These are great.
Indeed — I think when developing the compiler, it's easy for us to focus too much on "do we have a good algorithm for right-associative precedence", etc — but actually adding an equivalent for LIKE is much more important for most users. So these sorts of PRs have lots of impact.

As a followup, we might want to reconsider type text and std.from_text.

As a followup, we might want to reconsider type text and std.from_text.

I am OK with changing these if folks prefer...

Yeah, I think we should change those, because text is pretty much only used in the context of SQLite, in the rest of the computing world, it is string.
See: https://github.com/PRQL/prql/pull/3913#discussion_r1424049816

Sorry for coming late to this (I was away for a while) but I would throw in my vote in favour of text or str. I agree with @PrettyWood that string just seems to add extra characters for no benefit.
I also think our earlier discussions around text vs string still hold and text would be my preferred option.

For me the big downside of text is bytes vs strings. How do you differentiate them? I agree that often people want strings but not always! and even here there are subtleties like encoding, chars vs graphemes, ...

I think text would pretty much be a synonym for unicode strings. If you want bytes then you would need another type like bytea. I lived through the upheaval around this in the Python 2 to 3 transition but it's not something I've ever encountered in database work. Is it much of an issue there?
The closest I came was when working with MS SQL 15 years ago, you would sometimes get unexpected ordering depending on what collation you chose for your database. Is that still much of an issue these days? It's not something I've encountered in a long time so I really can't say.

To be honest my interest in PRQL is to simplify the refactoring of a custom DSL we have that translates many steps into Mongo, Polars and many SQL dialects.
If PRQL is first meant for data scientists/analysts who are not developers, maybe choosing text is better.
DuckDB went with that approach as well
I'm not familiar with the primary target of PRQL so I might be biased

Well, string is so widely popular in the computing worlds that I would think it probably is familiar even with non-developers such a data scientists and analysts.

I strongly agree with @snth: regardless of how it is named, type string or type text should contain UTF-8 encoded text. For arbitrary bytes there should be another type.
But I'm impartial on the name. A quick survey of exactly 1 person showed that string is not familiar to biologists, who tend to know the basics of R. On the other hand, string really is prevalent in the computing world.

A quick survey of a couple of others reinforces that "string" is actually not that well-known. From a program manager at SpaceX:

Not a lot to me. Something about a string of logic, but that's about it for me


FAB button is greyed out even after selecting a project

Describe the bug
After selecting a project the FAB button on the home screen remains greyed out
To Reproduce

Load ground app
Choose a project

Expected behavior
FAB button changes color (green IIRC) and becomes active
Actual behavior
FAB button stays greyed out and does nothing when you tap on it
Screenshots

Can you repro with the latest at HEAD?

Fixed with latest HEAD. Apologies, must remember to git pull regularly!


Correct typo from 'kubenetes' to 'kubernetes'

Description
Correct typo from 'kubenetes' to 'kubernetes'.

Thanks!


Variable interpolation in Kotlin

I added variables to description strings in my Kotlin code, like this:
@Parameters(paramLabel="TARGET", description = ["Any of the following: ${COMPLETION-CANDIDATES}"])

The result in the help text was that no text at all was printed for this parameter. Not even 'Any of the following:'.
After some experimentation I found that I had to escape the $-sign to make it work:
@Parameters(paramLabel="TARGET", description = ["Any of the following: \${COMPLETION-CANDIDATES}"])

This could perhaps be added to the manual.

@MagnusMG oh wow, I did not know about that, thank you for reporting this!
It seems that Kotlin has its own string interpolation, but the docs are a bit minimal. It appears that Kotlin uses the $ character to interpolate a variable and ${} to interpolate an expression. And my guess is that COMPLETION-CANDIDATES not being a valid expression causes the whole string to become... (what exactly?) ... bit strange error handling in my opinion, but okay.
The manual needs updating, agreed.
Do you feel like providing a pull request for this?

As I started looking into  changing the documentation, I noticed that the Kotlin code examples already have the dollar signs escaped. I somehow missed that.
That makes me less certain that a change of the manual is needed. Perhaps a short mention just under the first example. (The adoc files, are they for Asciidoctor or some other software?)

AsciiDoctor yes.
Maybe a CAUTION block after the first example in section 20.1 Variable Interpolation Example?

I have installed GitHub Desktop, checked out the source code, created a branch and adjusted the adoc file. However, when I convert index.adoc to html the result does not look quite like the original - the example code sections do not show up as alternatives that you select with a button, but rather they are listed one after the other. I assume I'm doing something wrong. I have tried running ./gradlew build in the root directory, but that does not seem to include the docs.

What is the path of the resulting HTML file you looked at?
The generated docs end up in build/docs/ somewhere (I think in a html5 directory).

The button vs sequential samples is a JavaScript plugin for AsciiDoctor.
What browser did you check the results in?
The task to just build the docs is:
./gradlew asci

I found the generated HTML file, and it looks fine, so I created a pull request. I haven't used GiutHub or git before, the GitHub documentation reminds me of the "Sea of Talmud", and I was not able to find a relevant guide, but I think I got it right in the end. Tell me otherwise.


Use react portal

Not sure who owns this stuff now but you might want to tag someone from that team 😃

oops. I agree. I added Greg Davis to the reviewers list. Thanks.


Update frameless-dataset to 0.11.1

Updates org.typelevel:frameless-dataset from 0.10.1 to 0.11.1.
GitHub Release Notes - Version Diff
I'll automatically update this PR to resolve conflicts as long as you don't change it yourself.
If you'd like to skip this version, you can just close this PR. If you have any feedback, just mention me in the comments below.
Configure Scala Steward for your repository with a .scala-steward.conf file.
Have a fantastic day writing Scala!

Ignore future updates
Add this to your .scala-steward.conf file to ignore future updates of this dependency:
updates.ignore = [ { groupId = "org.typelevel", artifactId = "frameless-dataset" } ]

labels: library-update, early-semver-major, semver-spec-minor

Btw this version brings support for Spark 3.2 and Scala 2.13. Would be great to have sparksql-scalapb support 2.13 as well.

I found this issue in frameless https://github.com/typelevel/frameless/issues/585. Does this possibly explain the issue I'm facing in https://github.com/scalapb/ScalaPB/issues/1286 ?

New versions of sparksql-scalapb will be published using different artifacts (to follow what frameless does as well). The artifact name should be changed from sparksql-scalapb to one of:

sparksql30-scalapb0_10
sparksql31-scalapb0_10
sparksql32-scalapb0_10
sparksql30-scalapb0_11
sparksql31-scalapb0_11
sparksql32-scalapb0_11

Depending on the Spark and ScalaPB version you would like to use. Current version is 1.0.0-M1. There's support for Scala 2.13 where applicable.
Can you try it out and let me know?

No, this does not resolve the issue.


Fix dropped frames calculation

The drop_frame_adjustment function could return a result that was 1-3 frames off. Took a stab at fixing it based on David Heidelberger's pseudocode and it seems to work correctly now.

Thank you for the PR!
It looks like there are a lot of unrelated changes due to your work being based on main instead of dev. main has a lot of extra files added by the release process in CI.
Would you mind making your changes to the dev branch of your fork instead, then make a new PR targeting this repo's dev?
Thanks!

Please also add some tests to assert that the bad cases have been fixed to prevent regressions!
Ideally we would also assert that the internal time representation equals the expected representation for the equivalent non-drop values.

Understood, I'll update the PR with the change on the dev branch, Clippy warning fixed, and tests added in the next day or two 👍


[BUG] Enqueued time is interpreted as a number instead of a datetime value

Describe the bug
When getting telemetry messages from an IoT Edge device using the IoT Hub Explorer, the system properties are represented like this:
"systemProperties": {
    "iothub-connection-device-id": "xxx-dev-edge-001",
    "iothub-connection-auth-method": "{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\",\"acceptingIpFilterRule\":null}",
    "iothub-connection-auth-generation-id": "637678139892935630",
    "iothub-enqueuedtime":<PHONE_NUMBER>356,
    "iothub-message-source": "Telemetry",
    "x-opt-sequence-number": 5733994,
    "x-opt-offset": "1017928807456",
    "x-opt-enqueued-time":<PHONE_NUMBER>418
  }

The property iothub-enqueuedtime is serialized as a number.
I believe this is incorrect, as per the documentation, the value of iothub-enqueuedtime should be a datetime object. From the docs:
iothub-enqueuedtime | Date and time the Device-to-Cloud message was received by IoT Hub.
If you connect a console app to the event hub compatible endpoint, and read the raw messages from there, you will see that this property is serialized as a datetimeoffset value:
partitionEvent.Data.SystemProperties["iothub-enqueuedtime"].ToString;
// Produces the following output:
10/03/2022 05:56:05

It seems to me that the value of this datetime object is serialized by the IoT Hub Explorer as a number, whereas the source of data is a datetime object.
Expected behavior
The telemetry data preserves its original data type.
Additional context
Running version 0.15.0

Hi @murdockcrc
We looked into the issue. The short answer is, Explorer does not modify any system properties, we show them as is.
The x-opt-enqueued-time is directly surfaced by the event hub node sdk that we uses, and here it what they return for example

We were wondering if it is sufficent for your use case to use this enqueueTime property directly, which is not in system properties:

If not, please let us know, and we will reopen the bug and route it to the event hub node sdk team.


code block syntax highlighting not working (Tree-sitter highlight injections through #BEGIN_SRC filetype blocks)

Everything seems to work for me except the code block syntax highlighting and I am really not sure why.
I pasted it just like that in my config and it's not working.
-- init.lua
-- Load custom treesitter grammar for org filetype
require('orgmode').setup_ts_grammar()
-- Treesitter configuration
require('nvim-treesitter.configs').setup {
-- If TS highlights are not enabled at all, or disabled via disable prop,
-- highlighting will fallback to default Vim syntax highlighting
highlight = {
enable = true,
-- Required for spellcheck, some LaTex highlights and
-- code block highlights that do not have ts grammar
additional_vim_regex_highlighting = {'org'},
},
ensure_installed = {'org'}, -- Or run :TSUpdate org
}
require('orgmode').setup({
org_agenda_files = {'~/Dropbox/org/', '~/my-orgs/**/'},
org_default_notes_file = '~/Dropbox/org/refile.org',
})

Do you have the following treesitter config?
    -- Setup treesitter
    require('nvim-treesitter.configs').setup({
      highlight = {
        enable = true,
        additional_vim_regex_highlighting = { 'org' },
      },
      ensure_installed = { 'org' },
    })


test loading lib

Hi! This is the friendly automated conda-forge-linting service.
I just wanted to let you know that I linted all conda-recipes in your PR (recipe) and found it was in an excellent condition.

Would be happy to add this if you are still interested.


docs: indicate default behavior and how to download all data

Hi,
Currently, documentation indicates that, by default, all data is downloaded.
So this PR aims to precise default behavior and how to download all data.

Thanks for the merge!